Elvyn Mejia February 2016

Resolving AngularJS promise returned by Factory function

I have a factory object that has a getProduct(id) function as shown below

angular.module('app')
    .factory('productFactory', ['$http', 'URL', function($http, URL){

        var urlBase = URL.APISERVER;

        //productFactory return object
        var productFactory = {};

        productFactory.getProducts = function(){
            return $http.get(urlBase + '/products/');
        }

        productFactory.getProduct = function(id){
            return $http.get(urlBase + '/products/' + id);
        }
        //return factory object
        return productFactory;
    }]);

In my controller I want to resolve the getProduct(id) promise. I am resolving this promise in another function getProduct(id) where I passed the product id.

angular.module('portal')
    .controller('ProductCtrl', ['$stateParams','productFactory', 
      function($stateParams, productFactory){
        //Using 'controller as syntax' in view
        var prod = this;

        //Saves status of promise
        prod.status;

        //Get a single product
        prod.product;

        //Get the product id from stateParams and pass that to
        //productFactory's getProduct(id) function
        var id = $stateParams.id;
        getProduct(id);//THIS IS WHAT CAUSES THE 500 ERROR

        //Resolves promise 
        function getProduct(id){
          productFactory.getProduct(id)
            .success(function(product){
              prod.product = product;
            })
            .error(function(error){
              prod.status = 'Unable to load product data' + error.message;
            });
        }


    }]);

However, when I invoke getProduct(id); in my controller I get 500 error and that's because I don't yet have access to the $stateParams.id when the controller compiles.

I have a list of products. When clicked on a particular product

Answers


James Choi February 2016

I use something like the following to resolve http requests using ui-router.

$stateProvider
    // nested list with custom controller
    .state('home.list', {
        url: '/list/:id',
        templateUrl: 'partial-home-list.html',
        resolve:{
          // Inject services or factories here to fetch 'posts'
          posts:function($http, $stateParams){
            return $http.get('//jsonplaceholder.typicode.com/posts/' + ($stateParams.id || 1));
          }
        },
        // resolved 'posts' get injected into controller
        controller: function(posts, $scope){
          $scope.posts = posts.data;
        }
    })

You can dependency inject productFactory instead of $http like I did. The posts key specified in resolve can be dependency injected into the controller specified as a function or as a string.

Post Status

Asked in February 2016
Viewed 1,153 times
Voted 7
Answered 1 times

Search




Leave an answer