Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 223
  • Last Modified:

AngularJS service to retain global data

I am new to angular and need to keep some global data throuhout my application.  The data I need to keep is a key-value pair data. Here is the service I am trying to add to my app:

 app.service("DataService", function (MyKey, MyValue) {
        var data_item = {};
        data_item.Key =MyKey;
        data_item.Value=MyValue;
        this.MyData.push(data_item);

    });

Open in new window


Is what I am doing correct?

Also how do I access this service to add data or to retrieve data? Do I need to inject this service into each controller?
0
YZlat
Asked:
YZlat
  • 7
  • 7
3 Solutions
 
Julian HansenCommented:
Also how do I access this service to add data or to retrieve data? Do I need to inject this service into each controller?

Yes you would here is an example
<divng-controller="mainCtrl as ctrl">
  <ul>
    <li ng-repeat="(key,value) in ctrl.items">
      <label>{{key}}</label> =&gt; {{value}}
    </li>
  </ul>
  <input ng-model="ctrl.newKey" />
  <input ng-model="ctrl.newValue" />
  <button ng-click="ctrl.addItem(ctrl.newKey, ctrl.newValue)">Add</button>
</div>

Open in new window

Angular
(function() {
  'use strict';
  angular.module('app',[])
    .controller('mainCtrl', mainController)
	
    // Create the service 
    .factory('DataService', function() {
      // Create a reference to ourself
      var vm = this;
    
      // Initialise the data structure
      vm.data = { };
    
      // Function to set an item in the map
      var setItem = function(key, value) {
        vm.data[key] = value;
      }
    
      // Function to retrieve a value from the map
      var getItem = function(key) {
        if (vm.data[key] != undefined) {
          return vm.data[key];
        }
        return false;
      }
    
      // Function to get all the items in the map
      var getAllItems = function() {
        return vm.data;
      }
      
      // return our interface
      return {
        setItem: setItem,
        getItem: getItem,
        getAllItems: getAllItems
      }
    })
  
  // Controller function
  function mainController(DataService)
  {
    // Create a reference to ourself
    var vm = this;
  
    // Initialise with the DataService items
    vm.items = DataService.getAllItems();
  
    // Handle the Add Item button click
    vm.addItem = function(key, value) {
      DataService.setItem(key, value);
	  
      // Clear the inputs
	  vm.newKey = vm.newValue = '';
    }
  }
})();

Open in new window

Working sample here
0
 
Julian HansenCommented:
A note on your original code -
 app.service("DataService", function (MyKey, MyValue) {
        var data_item = {};
        data_item.Key =MyKey;
        data_item.Value=MyValue;
        this.MyData.push(data_item);

    });

Open in new window

When we setup a service we inject the dependencies we want to use in the service not the values we will be adding to it. That is done with functions as shown in the example in the previous post.
0
 
YZlatAuthor Commented:
@Julian Hansen, I do not want to use factory, but service
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
YZlatAuthor Commented:
also i will not be using ng-model in inputs, but variables from my controllers. I want to add items to the array from the controller code
0
 
Julian HansenCommented:
@Julian Hansen, I do not want to use factory, but service
They are effectively the same thing, A factory just allows you to run some initialisation code before instantiating the factory object - but once instantiated they are identical in every way. To change the factory into a service just do this
    .service('DataService', function() {
      // Create a reference to ourself
      var vm = this;
    
      // Initialise the data structure
      vm.data = { };
    
      // Function to set an item in the map
      vm.setItem = function(key, value) {
        vm.data[key] = value;
      }
    
      // Function to retrieve a value from the map
      vm.getItem = function(key) {
        if (vm.data[key] != undefined) {
          return vm.data[key];
        }
        return false;
      }
    
      // Function to get all the items in the map
      vm.getAllItems = function() {
        return vm.data;
      }
    })

Open in new window

Working sample here
also i will not be using ng-model in inputs, but variables from my controllers. I want to add items to the array from the controller code
The controller is adding the data
      vm.items = DataService.getAllItems();
      ...
      DataService.setItem(key, value);

Open in new window

Where you get the key values from is irrelevant - the method of adding them to the service is the same.
0
 
YZlatAuthor Commented:
@Julian Hansen my data sample is actually different. It is not a conventional key-value pair but just a pair of values, I just might not have expressed myself correctly.

So I'd need to store an array of two-value items.
Could I do something like that?

 vm.setItem = function(FirstID, SecondID) {
     	data_item.FirstID=FirstID;
        data_item.SecondID=SecondID;
        vm.data.push(data_item);
      }

Open in new window

0
 
Julian HansenCommented:
There is no problem with doing that.
Updated HTML
<ul>
  <li ng-repeat="item in ctrl.items">
    <label>{{item.FirstID}}</label> =&gt; {{item.SecondID}}
  </li>
</ul>

<input ng-model="ctrl.FirstID" />
<input ng-model="ctrl.SecondID" />

<button ng-click="ctrl.addItem(ctrl.FirstID, ctrl.SecondID)">Add</button>
<input ng-model="ctrl.Search" />

<button ng-click="ctrl.findItem(ctrl.Search)">Search</button>
<div>Found: {{ctrl.searchItem}}</div>

Open in new window

Updated service
.service('DataService', function() {
  // Create a reference to ourself
  var vm = this;

  // Initialise the data structure
  vm.data = [];

  // Function to set an item in the map
  vm.setItem = function(FirstID, SecondID) {

	var new_item = {
		FirstID: FirstID,
		SecondID: SecondID
		
	}
	vm.data.push(new_item);
  }

  // Function to retrieve a value from the map
  vm.getItem = function(FirstID) {
	for(var k in vm.data) {
		if (vm.data[k].FirstID == FirstID) {
			return vm.data[k];
		}
	}
	
	return false;
  }

  // Function to get all the items in the map
  vm.getAllItems = function() {
	return vm.data;
  }
})

Open in new window

Revised sample here
0
 
YZlatAuthor Commented:
Thank you!

I defined the service in y base controller as follows:

(function () {
    var app = angular.module("MyApp", ["ui.router"]);

    app.controller("BaseCtrl", ["$scope", "$http", "$state", BaseControllerFunc]);

    function BaseControllerFunc($scope, $http, $state) {
        
       ...
    }
    
    //add service
    app.service("DataService", function () {
        // Create a reference to ourself
        var vm = this;

        // Initialise the data structure
        vm.data = {};

        // Function to set an item in the map
        vm.setItem = function (FirstID, SecondID) {
            vm.data[FirstID] = SecondID;
        }

        // Function to retrieve a value from the map
        vm.getItem = function (FirstID) {
            if (vm.data[FirstID] != undefined) {
                return vm.data[FirstID];
            }
            return false;
        }

        // Function to get all the items in the map
        vm.getAllItems = function () {
            return vm.data;
        }

    });
//end add service

})();

Open in new window



Now I have a number of controllers in the following format:

angular.module("MyApp").controller("MyCtrl", ["$scope", "$state", "$http", MyCtrlFunction]);

function MyCtrlFunction($scope, $state, $http) {

  ...

}

Open in new window


How do I inject my service into my controllers?
0
 
Julian HansenCommented:
angular.module("MyApp")
  .controller("MyCtrl", ["$scope", "$state", "$http", "DataService", MyCtrlFunction]);

function MyCtrlFunction($scope, $state, $http, DataService) {

  ...

}

Open in new window

You can read more about Angular dependency injection here
0
 
YZlatAuthor Commented:
Thank you! Will test it out
0
 
YZlatAuthor Commented:
One last thing. I have utilized the second version you provided:

.service('DataService', function() {
  // Create a reference to ourself
  var vm = this;

  // Initialise the data structure
  vm.data = [];

  // Function to set an item in the map
  vm.setItem = function(FirstID, SecondID) {

	var new_item = {
		FirstID: FirstID,
		SecondID: SecondID
		
	}
	vm.data.push(new_item);
  }

  // Function to retrieve a value from the map
  vm.getItem = function(FirstID) {
	for(var k in vm.data) {
		if (vm.data[k].FirstID == FirstID) {
			return vm.data[k];
		}
	}
	
	return false;
  }

  // Function to get all the items in the map
  vm.getAllItems = function() {
	return vm.data;
  }
})

Open in new window


First I add data and then try to check what got added:

DataService.setItem(1, "Test");
console.log("data added is " +DataService.getItem(1).SecondID);

Open in new window


and get an error:

TypeError: Cannot read property 'SecondID' of undefined

Open in new window

0
 
Julian HansenCommented:
Did a copy and paste of both lines to my sample - works fine

Updated controller
  // Controller function
  function mainController(DataService)
  {
    // Create a reference to ourself
    var vm = this;
	
	DataService.setItem(1, "Test");
	console.log("data added is " +DataService.getItem(1).SecondID);

	// Initialise with the DataService items
    vm.items = DataService.getAllItems();
	vm.searchItem = false;
	vm.findItem = function(item) {
		vm.searchItem = DataService.getItem(item);
	}
    // Handle the Add Item button click
    vm.addItem = function(key, value) {
      DataService.setItem(key, value);
	  
      // Clear the inputs
	  vm.FirstID = vm.SecondID = '';
    }
  }

Open in new window

Updated sample here
View result in console.
0
 
YZlatAuthor Commented:
Thank you for all your help!
0
 
Julian HansenCommented:
You are welcome.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now