Trace
Trace

Reputation: 18869

Angular store variable in service

I'm currently reading ng-book, and just wondered if this code example related to services is good practice:

To share data across controllers, we need to add a method to our service that stores the username. Remember, the service is a singleton service that lives for the lifetime of the app, so we can store the username safely inside of it.

angular.module('myApp.services', [])
    .factory('githubService', function($http) {
        var githubUrl = 'https://api.github.com',
            githubUsername;
        var runUserRequest = function(path) {
        // Return the promise from the $http service
        // that calls the Github API using JSONP
        return $http({
            method: 'JSONP',
            url: githubUrl + '/users/' +
            githubUsername + '/' +
            path + '?callback=JSON_CALLBACK'
        });
    }
    // Return the service object with two methods
    // events
    // and setUsername
    return {
        events: function() {
            return runUserRequest('events');
        },
        setUsername: function(username) {
            githubUsername = username;
        }
    };
});

Now, we have a setUsername method in our service that enables us to set the username for the current GitHub user.

I wonder, this way the username doesn't persist when you open a new tab. Isn't it better to use localstorage / cookies to keep this kind of state for the application?

Is this good practice in general?

Upvotes: 2

Views: 3614

Answers (2)

Cesar Alvarado
Cesar Alvarado

Reputation: 111

You could do Both. Keeping this kind of data inside the Service in private variables Can isolate it and you can control read/write to do some sort of validation. This way you are not allowing the modification of the data anywhere else but inside the Service.

What you can do is to add a save function inside the service that saves the desired data inside the storage and a public recall function that gets called on the app.run method.

Your service :

angular.module('myApp.services', [])
  .factory('githubService', function($http) {
    var githubUrl = 'https://api.github.com',
      githubUsername;
    var runUserRequest = function(path) {
      // Return the promise from the $http service
      // that calls the Github API using JSONP
      return $http({
        method: 'JSONP',
        url: githubUrl + '/users/' +
          githubUsername + '/' +
          path + '?callback=JSON_CALLBACK'
      });
    }
    //Saves the data inside localStorage
    var save = function() {
      localStorage.setItem('githubData', guthubUserName);
    }

    // Return the service object with two methods
    // events
    // and setUsername
    return {
      events: function() {
        return runUserRequest('events');
      },
      setUsername: function(username) {
        githubUsername = username;
        save(); // keeps the username always up to date
      },
      recall : function(){
        githubUsername = localStorage.getItem('githubData');
      }  
    };
  });

Your main.js: var app = app.module('yourGitHubApp', ['myApp.services'])

app.run(function(githubService){
 githubService.recall();
})

So each time the applications gets reloaded the data from localStorage would be refreshed.

Upvotes: 1

dfsq
dfsq

Reputation: 193261

I wonder, this way the username doesn't persist when you open a new tab.

Because if you open an app in the new tab, the entire app code base gets reinitialized again, including githubService so githubUsername is default again.

If you need the state to persist across application reloads, then you should use some kind of storage, like localStorage.

Upvotes: 0

Related Questions