Solved

AngularJS service to retain global data

Posted on 2016-10-13
14
92 Views
Last Modified: 2016-10-18
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
Comment
Question by:YZlat
  • 7
  • 7
14 Comments
 
LVL 56

Assisted Solution

by:Julian Hansen
Julian Hansen earned 500 total points
ID: 41842408
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
 
LVL 56

Expert Comment

by:Julian Hansen
ID: 41842420
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
 
LVL 35

Author Comment

by:YZlat
ID: 41842431
@Julian Hansen, I do not want to use factory, but service
0
Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

 
LVL 35

Author Comment

by:YZlat
ID: 41842436
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
 
LVL 56

Expert Comment

by:Julian Hansen
ID: 41842481
@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
 
LVL 35

Author Comment

by:YZlat
ID: 41846717
@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
 
LVL 56

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 41846761
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
 
LVL 35

Author Comment

by:YZlat
ID: 41846898
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
 
LVL 56

Assisted Solution

by:Julian Hansen
Julian Hansen earned 500 total points
ID: 41847033
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
 
LVL 35

Author Comment

by:YZlat
ID: 41847152
Thank you! Will test it out
0
 
LVL 35

Author Comment

by:YZlat
ID: 41847231
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
 
LVL 56

Expert Comment

by:Julian Hansen
ID: 41847317
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
 
LVL 35

Author Closing Comment

by:YZlat
ID: 41848173
Thank you for all your help!
0
 
LVL 56

Expert Comment

by:Julian Hansen
ID: 41848276
You are welcome.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, we'll look how to sort an Array in JavaScript, including the more advanced techniques of sorting a collection of records either ascending or descending on two or more fields. Basic Sorting of Arrays First, let's look at the …
Article by: DanRollins
This article describes a JavaScript program that creates a maze made of hexagonal cells.  In Part 2 (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_7850-Hex-Maze-Part-2.html), we'll extend the program by adding a depth-…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

735 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question