0

In app.js, I resolve a ui-router thusly:

           .state('edit', {
                url: '/edit/:id',
                templateUrl: '/ang/views/edit/editapp.html',
                resolve: {
                    loan: function ($q, $stateParams, Loans) {
                        var p = $q.defer();
                        Loans.getLoan($stateParams.id)
                            .then(function (res) {
                                p.resolve(res);
                            });
                        return p.promise;
                    }
                },
                controller: 'EditAppController'
            })

I have a Loans factory where this promise is resolved and in the EditAppController, I send the object back to the factory for further processing using

$scope.loan = Loans.makeLoan(loan.data.data);

Here is the pertinent part of my Loans Factory:

.factory('Loans', function($http){
    return {
        getLoan: function(id){
            return $http.get('/api/loans/' + id);
        },
        makeLoan: function(o){
            o.jwg = 'This added in make loan';
            return o;
        };

In the makeLoan() method, I just did something to prove to me that this work. What I NEED to do is to make another $http call to the API to get some additional data and I NEED to resolve that call within the same method (makeLoan()) so that I can add some calculations to the object within this function before giving it to the controller for the view.

Can someone explain to me how I can do this?

jgravois
  • 2,559
  • 8
  • 44
  • 65
  • Use promise chaining, eg `return $http.get('/whatever').then(function(res) { /* do stuff */ })`. See https://docs.angularjs.org/api/ng/service/$q#chaining-promises – Phil Oct 27 '14 at 03:11
  • wow, didn't know you could chain a then to the promise itself...thanks. One additional question, can I do a $q there and make several API calls there? – jgravois Oct 27 '14 at 03:13
  • It's your code ;). You might be interested in `$q.all()` if you want to execute something after a bunch of promises are resolved. – Phil Oct 27 '14 at 03:14

1 Answers1

1

If you need to make 2 calls to the API and you want to retrieve just the promise of the last call, you can chain the promises. This will only return the last promise:

    makeLoan: function(){
        return $http.get('/api/loans/whatever').then(function(data){ 
                    return $http.get('/api/loans/whatever2/'+data.id); 
               });
    }

Also, if I may: what you are doing here:

       .state('edit', {
            url: '/edit/:id',
            templateUrl: '/ang/views/edit/editapp.html',
            resolve: {
                loan: function ($q, $stateParams, Loans) {
                    var p = $q.defer();
                    Loans.getLoan($stateParams.id)
                        .then(function (res) {a
                            p.resolve(res);
                        });
                    return p.promise;
                }
            },
            controller: 'EditAppController'
        })

It's an anti-pattern known as deferred anti-paattern, a better way to do it would be:

       .state('edit', {
            url: '/edit/:id',
            templateUrl: '/ang/views/edit/editapp.html',
            resolve: {
                loan: function ($stateParams, Loans) {                        
                    return Loans.getLoan($stateParams.id);
                }
            },
            controller: 'EditAppController'
        })
Community
  • 1
  • 1
Josep
  • 12,926
  • 2
  • 42
  • 45