Solved

AngularJS service to retain global data

Posted on 2016-10-13
14
40 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 51

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 51

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
 
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 51

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 51

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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
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 51

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 51

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 51

Expert Comment

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

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

In my daily work (mainly using ASP.net), I need to write a lot of JavaScript code. One of the most repetitive tasks I do are the jQuery Ajax calls. You know: (CODE) I don't know if for you it's the same, but for me is soooo tedious to write the …
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
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…

746 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now