Contact Manager – written in AngularJS, Express and MongoDB – Episode 3
Older Article
This article was published 13 years ago. Some information may be outdated or no longer applicable.
This is the final piece of the Contact Manager series, covering how to view individual contacts. To make this work, we need to introduce routing on the AngularJS side, building on the routing we set up in the first article.
Routing in AngularJS couldn’t be simpler. Everything runs through the $route service. Plenty of good articles out there explain how to use this service and how to configure your routes via the $routeProvider service.
With all that in hand (and assuming you’ve read the documentation), we need to extend the script from the previous post:
angular.module('contactmanager', ['filters']).config(function ($routeProvider) {
$routeProvider
.when('/', { controller: ListController, templateUrl: 'list.html' })
.when('/contacts/', {
controller: ListController,
templateUrl: 'list.html',
})
.when('/contacts/:id', {
controller: ViewController,
templateUrl: 'contact.html',
})
.when('/add/', { controller: AddController, templateUrl: 'add.html' })
.otherwise({ redirectTo: '/' });
});
We’re telling Angular which controller and template to load for each path.
Each controller lets us trigger separate actions, and their scopes apply only to their respective HTML files. Let’s look at the ViewController first. If you remember from the first article, it lets you view a single contact.
function ViewController($scope, $http, $routeParams) {
$http({
method: 'jsonp',
url:
'http://host:1222/contacts/' +
$routeParams.id +
'?callback=JSON_CALLBACK',
})
.success(function (data, status, headers, config) {
$scope.contact = data;
})
.error(function (data, status, headers, config) {
//do something to handle the error
});
}
Any URL matching the /contacts/:id pattern (where :id is our _id from MongoDB) gets handled by the ViewController, which loads contact.html.
A sample call to view a contact looks like this:
<a href="#/contacts/{{ contact._id }}">{{ contact.name }}</a>
We store the returned JSONP object against the contact scope so we can reference it in our HTML. Here’s a (rather plain) file using that scope:
<div>You are looking at : {{ contact.name }}</div>
We already set up the save method when we built the backend. That function receives data and stores it in MongoDB. But we also need to handle data addition from the frontend. As you can see above, there’s another controller: AddController. It collects data from our form and submits it to the right backend route, which then writes into the database.
function AddController($scope, $http, $location) {
$scope.form = {};
$scope.addContact = function () {
$http.post('/contact', $scope.form).success(function (data) {
$location.path('/');
});
};
}
And the corresponding HTML should look something like:
<input input ng-model="form.name" name="name" />
<input ng-model="form.phone" name="phone" />
<button ng-click="addContact()">Add Contact</button>
$scope.form collects all the information from the representative model via the HTML form. We attach the addContact() method to a button that fires the post method from our API (again, refer back to the first article). On a successful addition, we redirect the user to the root path using the $location service.
That wraps it up. I’ll leave you to figure out the edit/delete controllers. Trust me, they’re not complicated at all. You’d just need to extend your routes, add methods, and create HTML templates that let you manipulate the models you’ve built.