2

I'm trying to create a custom service which pulls the list of all defined statuses from the server for use in forms, so far I have:

SimpleTaskApp.factory('storyStatus', function($http) {
    var data = null;
    var promise = $http({
            url: '/story-status/',
            method: 'GET'
        }).success(function (resp) {
            data = resp;
        });
    return {list: data }};
});

I understand this won't work since $http is asynchronous, however I have no desire to run the request more than once. I'd like to treat it as a static variable in effect, so if ever storyStatus.list is called, it should check whether it is empty and then attempt to populate itself.

2 Answers 2

2

You should work with promises instead of against them.

You don't need to store the data because you can store the promise. The point of promises is that you don't know when they'll be done. You don't know when your data will be available.

So your service must return the promise. But that's okay:

SimpleTaskApp.factory('storyStatus', function($http) {
  var promise;

  function getData() {
    if ( ! angular.isDefined( promise ) ) {
      promise = $http({
        url: '/story-status/',
        method: 'GET'
      });
    }

    return promise;
  }

  return { list: getData };
});

In this service, your $http call will only be called once, but will return a promise whenever you call SimpleTaskApp.list(). Your controller that calls it doesn't need to know if the data is there yet because it will react the same regardless, e.g.:

SimpleTaskApp.controller('MainCtrl', function($scope, storyStatus) {
  storyStatus.list().then(function( data ) {
    $scope.statuses = data.statuses;
  });
});

If the data is already retrieved, the then will run basically immediately; if not, it will run when the data gets back. The controller doesn't need to know anything about the internal state of the storyStatus service.

So promises not only help with asynchronous tasks, but they also help keep our components decoupled, which is a big deal in AngularJS - and should be in other frameworks too!

Sign up to request clarification or add additional context in comments.

Comments

1

You could do this maybe?

SimpleTaskApp.factory('storyStatus', function($http) {

    var promise = $http({
        url: '/story-status/',
        method: 'GET'
    });

    return { list: promise };
});

Calling code

storyStatus.list.then(function (data) {
});

You might want to consider using a synchronous ajax call to simplify your API if you are only loading the list once.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.