svbox
svbox

Reputation: 1

How to start a directive after a promise has finished

I have the following service:

app.factory('Words', ['$http', '$q', function($http, $q) {
    return {
        getWords: function() {
        var defer = $q.defer();
        $http.get('words.json', {cache: 'true'}).success(function(data) {
                defer.resolve(data);
            });
            return defer.promise;
        }
    };
}]);

I also have a directive where I inject the above service. In the json file I have objects of words with id and description.

app.directive('word', ['Words', '$http', function(Words, $http) {
    var newWords;
    Words.getWords().then(function(data) {                                                                                                                                 
        newWords = data;
    }); 
    return {
        scope: {id: '@'},
        template : function(elem, attr) {
            var res;
            for (var i = 0; i <= newWords.length; i++) {
                if (i == attr.id) {
                    res = '<div>'+ newWords[i].description +'</div>';
                }
            }
            return res;
        }
    };
}]);  

Ideally, I would like to return the description of a word depending of the value that I pass in the id attribute of the directive. I understand that service is asynchronous but I do not know how to do it.

Upvotes: 0

Views: 27

Answers (1)

charlietfl
charlietfl

Reputation: 171669

You are trying to parse words array before the request has completed.

Need to parse them in a then() and return string to then and return the promise from template function

Try

app.directive('word', ['Words',  function(Words) {

    return {
      scope: { id: '@'},
      template: function(elem, attr) {
        return Words.getWords().then(function(data) {

          var res;
          for (var i = 0; i <= data.length; i++) {
            if (i == attr.id) {
              res = '<div>' + newWords[i].description + '</div>';
            }
          }
          return res;
        });
      }
    };
  }
]);

Also note that you are using a $q anti-pattern in the service since $http returns a promise

Can cut it down to:

app.factory('Words', ['$http',  function($http) {
    return {
        getWords: function() {            
            return  $http.get('words.json', {cache: 'true'}).then(function(response) {
                return response.data;
            });               
        }
    };
}]);

Upvotes: 1

Related Questions