Resolve not firing the service function

300
April 23, 2017, at 02:53 AM

I am new to angular, looked up relevant questions but could not find anything useful. I hope someone can offer some insight as I spent an entire day on this to no avail: I am trying to use resolve to get data using $resource and ui-router for my applciation. The problem is that the call to the service method never gets made (the call is defined int eh resolve property') although the state seems to load fine. (The state actually has a ui-grid so currently the grid appears empty). The application is using a json-server to provide data for now , the server does not show any http request. Please find some relevant code below: The state provider config:

angular.module('carsApp', ['ui.router', 'ngResource', 'ui.bootstrap', 'ui.grid']) 
  .config(function($stateProvider, $urlRouterProvider) { 
    $stateProvider 
      // abstract state for 'car' state. Creates view template with two sub tabs. 
 
      .state('app.main.car', { 
        url: "", 
        abstract: true, 
        views: { 
          // the child template (Absolutely named) 
          'contentbar@app.main': { 
            templateUrl: 'views/crid.html', 
            controller: 'GridController' 
          }, 
 
          'subTabs@app.main': { 
            templateUrl: 'views/cars.html', 
            controller: 'CarController' 
 
          } 
        }, 
        resolve: { 
          // create an Object property called "cars" 
          // which will later be used for Dependency Injection 
          // inside our Controller. Inject any Services required to resolve the data 
          cars: ['gridFactory', function(gridFactory) { 
            // Return Service call, that returns a Promise 
            return gridFactory.getCars(); 
          }], 
          dealer: function() { 
            return {}; 
          } 
        } 
      }) 
 
      .state('app.main.car.all', { 
        url: "car/summary", 
        views: { 
 
          'subTabView@app.main.car': { 
            templateUrl: 'views/summary.html' 
 
          } 
        }, 
        resolve: { 
          cars: ['gridFactory', function(gridFactory) { 
            // Return Service call, that returns a Promise 
            return gridFactory.getCars(); 
          }], 
          dealer: function() { 
            return {}; 
          } 
        } 
      }); 
 
    $urlRouterProvider.otherwise('/'); 
  });

the service:

.service('gridFactory', ['$resource', 'baseURL', function($resource, baseURL) { 
 
        this.getCars = function() { 
          return $resource(baseURL + "cars", null, { 
            'query': { 
              method: 'GET', 
              isArray: true, 
              // im setting authroization header here so using this version 
              // of query to be able to add headers 
 
            } 
          }); 
        } 
 
 
      }

the controller:

.controller('GridController', ['$scope', '$stateParams', '$state', 'gridFactory', 'cars', 'dealer', function($scope, $stateParams, $state, gridFactory, cars, dealer) { 
 
        $scope.cars = cars; //i am not sure if this is the correct way to assign. Looking up at  
        //all the blog posts i could, this is what i understood 
        $scope.dealer = dealer; 
 
        console.log('scope objects ' + JSON.stringify($scope.cars)); //$scope.cars is undefined here 
 
        //grid related code follows. Not shown here to keep things simple. 
 
        // the grid is apparently working as i was able to get data without using resolve. 
        // some context on why i want to use resolve: 
        // I want the grid to refresh whenever an entry on the grid is clicked, the corresponding details 
        // for that entry are fetched from gridFActory using resource and displayed in the grid again. 
        // However, the grid was not being refreshed ( i was using a child controller for a the .all state, 
        // i tried every trick on stackoverflow to make it work but giving 'resolve' a go as a final attempt) 
 
      }

I hope someone can offer some insight as to what I am missing. Many thanks for your time!

Answer 1

Need to call the query() method and return the $resource promise instead. By default $resource methods return an empty object or array that gets populated after the request completes

resolve: {          
      cars: ['gridFactory', function(gridFactory) {
        // Return Service call, that returns a Promise
        return gridFactory.getCars().query().$promise;
      }],
      dealer: ....

You could also move some of this call into the service method and have it return the query().$promise

DEMO

Answer 2

I suppose problem in your factory get cars method:

Try following:

 .service('gridFactory', ['$resource', 'baseURL', function($resource, baseURL) {
    this.getCars = function() {
      var cars =  $resource(baseURL + "cars", null, {
        'query': {
          method: 'GET',
          isArray: true,
          // im setting authroization header here so using this version
          // of query to be able to add headers
        }
       return new Promise(function(resolve, reject){
          var result = [];
          cars.query(function (response) {
             angular.forEach(response, function (item) {
               result.push(item);
             }
          }
          resolve(result);
        })
       })
      });
    }

  }

I think this question is related to yours

READ ALSO
how i can create multi image with different Location in javascript?

how i can create multi image with different Location in javascript?

how i can create 14 image with different Location ( Random Location ) in html using javascript ?

351
C++ back-end - Javascript front-end [on hold]

C++ back-end - Javascript front-end [on hold]

I want to create a simple website using C++ as my back-end and Javascript as my front-end, but I'm a completely newbie when it comes to web developmentWhat do I need to know/use in order to accomplish this that I want to do?

377
Webpack Javascript Modules

Webpack Javascript Modules

I'm trying to learn a bit about javascript modules and webpack

389