0

I have a factory that looks like such:

app.factory('thingFactory', function($http) {

    var factory = {};   
    var things = [];

    factory.refreshThings = function() {
        return $http.post('/GetThings');
    }

    factory.initializeThings = factory.refreshThings()
        .then(function(response) {
            things = response.data;
        }, function(response){
            // some error handling code here...
        });

    factory.getThings = function() {
        return things;
    }

    return factory;
}

and a controller

app.controller('myController', function($scope, thingFactory) {
    $scope.things = thingFactory.getThings();
}

Because of the asynchronous nature of promises, and other collections being initialized (in addition to things), should I be concerned with getThings() returning an empty array, and thus, returning before the $http.post() call has resolved?

Is this a better alternative?

app.controller('myController', function($scope, thingFactory) {
    $scope.things = []

    thingFactory.initializeThings
        .then(function(response) {
            $scope.things = response.data;
        }, function (response) {
            // some error handling code here...
        });
}

Is there a safe alternative, where I can get the controller to not think about the promise and just safely get the collection from the factory?

1
  • Why not just make getThings return a promise? Commented Jan 28, 2015 at 17:44

1 Answer 1

1

You're code is definitely going to be problematic. The factory will not be instantiated until it is used by a controller, so things will not be initialized until it is called by a controller, at which time initializeThings will get called right before you call getThings, which will likely return an empty array. Also, it's never a good idea to follow a "let's hope it's there" approach.

I see two approaches you can take: getThings accepts a callback as an argument or it returns a promise, which could look something like this:

  1. Callbacks - I prefer callbacks over promises, but that's a personal thing. Also, I use NodeJS-inspired syntax:

    var things; // no need to initialize array
    
    // callback -> function (error, things) {}
    factory.getThings = function (callback) {
      if (things) {
        return callback(null, things);
      }
    
      factory.refreshThings()
        .then( function (response) {
            things = response.data;
            return callback(null, things);
        }, function (reason) {
            return callback(reason);
        });
    }
    
  2. Promises - not the best syntax, but you get the idea

    factory.getThings = function () {
      var d = $q.defer();
      // I'm sure there's a better way to do this, but setting
      // this in a timeout will allow the promise to return so that
      // you can try to return it.
      $timeout( function () {
        if (things) {
           return d.resolve(things);
        }
    
        factory.refreshThings()
          .then( function (response) {
            things = response.data;
            return d.resolve(things);
          }, function (reason) {
            return d.reject(reason);
          });
      });
    
      return d.promise;
    }
    

As a side note, if you're using a RESTful API, GET should be used to get information rather than POST.

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

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.