HTTP is a stateless protocol. Each time a client retrieves a new information, it opens a seperate connection to the web / application server. The server does not automatically maintains the contextual information of the client. It leads to many difficulties. Typical example being the online store. User adds the products on the cart by visiting various views.
There are various solutions available to maintain the session.
e.g. using the cookies, URL re-writting and using the hidden fields.
In online store application created using angular we can also maintain the state of the cart across the various views and controllers.
How we can do it in angular?
Angular provides a way to create services using various recipes which can hold the data.
Step 1. Create a service using value recipe.
Step 2. Create a cart object inside this service.
Step 3. Provide the cart manipulation operations like update, delete, add Cart to this service.
step 4: Inject this service to the controllers in the online store application.
step 5. Angular makes the service available to all the controllers wherever this cart Service is injected.
When the angular application bootstraps, it creates service which holds the empty cart object.
All objects in angular being singleton the same object is made available to all the controllers thereby maintaining the state of the cart across the views.
Online store example
In typical shopping cart we buy products on various product / category pages and keep updating the cart. Here are the steps.
Step 1: Create the angular application file say main.js
var app = angular.module('shopingCart', ['ngRoute']); app.config(['$routeProvider', function($routeProvider) { $routeProvider .when('/page1', { tempateUrl: 'page1.html', controller: 'page1cntrl' }) .when('/page2', { templateUrl: 'page2.html', controller: 'page2cntrl', }) .when('/showCart', { templateUrl: 'cart.html', controller: 'cartcntrl', }) .otherwise({ // default action of route redirectedTo: '/page1' }) }]);Step 2: Create the index.html file
Shopping Cart
Step 3 : Create a js file called session-service.js
Here we create the custom injectable service having a cart inside using the "value provider recipe".
'use strict'; function Cart() { return { 'cartId': '', 'cartItem': [] }; } // custom service maintains the cart along with its behavior to clear itself , create new , delete Item or update cart app.value('sessionService', { cart: new Cart(), clear: function() { this.cart = new Cart(); // mechanism to create the cart id this.cart.cartId = 1; }, save: function(session) { this.cart = session.cart; }, updateCart: function(productId, productQty) { this.cart.cartItem.push({ 'productId': productId, 'productQty': productQty }); }, //delete Item and other cart operations function goes here... });
Product page 1 and its controller
page1.html
Product 1 Page
Added to Cart
page1cntrl.js
'use strict'; angular.module('shopingCart').controller('page1cntrl',['$scope','sessionService',function($scope,sessionService){ // in this controller the sessionService has been injected as dependency // retrieve the session information from the service to the scope using the following stt. $scope.sessionData = sessionService; $scope.updateCart = function(id,qty) { $scope.itemBought = true; sessionService.updateCart(id,qty); // call the service method to update the cart. }; }]);
page2.html
Product 2 Page
Added to Cart
page2cntrl.js
'use strict'; angular.module('shopingCart').controller('page1cntrl',['$scope','sessionService',function($scope,sessionService){ // in this controller the sessionService has been injected as dependency // retrieve the session information from the service to the scope using the following stt. $scope.sessionData = sessionService; // for demo and understanding purpose we have duplicated the same method in the two controllers. // how ever we can create the commonMethods which can be accessed from various different controllers. I will soon be posting how to create the common methods which can be accessed by different controllers. $scope.updateCart = function(id,qty) { $scope.itemBought = true; sessionService.updateCart(id,qty); // call the service method to update the cart. }; }]);cart.html
Cart
Product id | product Qty |
---|---|
{{cartItem.id}} | {{cartItem.qty}} |
Cart is Empty
'use strict'; angular.module('shopingCart').controller("cartcntrl", ['$scope','sessionService', function($scope,sessionService) { $scope.sessionData = sessionService; $scope.varShowCart = true; sessionService.save($scope.sessionData); }]);
Note:
This session object needs to be stored in local storage like "$window.sessionStorage" , session object or any other mechanism. The current object will be lost once the user refreshes the page.
Further reading
There are different recipes (methods) using which we can create custom angular service these are
1. Service
2. Factory
3. Value
4. Constant and
5. $provide
The first 4 are the specialized version of the $provide. For more details you can refer https://docs.angularjs.org/api/auto/service/$provide