americruiser
americruiser

Reputation: 85

AngularJS: Unable to pass a factory's $http.get result to the controller (via $routeProvider)

I have a CRUD operation I would like to reuse, so I have a factory that gets passed to the controller via the $routeProvider/resolve.

But I see that the controller resolves before the factory's GET request comes back. How can I set up promises so that $routeProvider doesn't pass undefined to the controller?

My example:

angular
  .module('app',['ngRoute'])
  .config(config)
  .controller('appController', appController)
  .factory('appFactory', appFactory);

function config($routeProvider){
  $routeProvider
    .when('/',{
      templateUrl: 'template.html',
      controller: 'appController',
      resolve: {
        server_stuff: function(appFactory){
          // logging
          console.log('appFactory.serverReponse = '+ appFactory.serverResponse() );
          return appFactory.serverResponse();
        }
      }
    });
}

function appController( $scope, server_stuff ){
  $scope.content = server_stuff;
  // logging
  console.log('server_stuff = '+server_stuff);
}

function appFactory($http){
  var i = 1;
  var appFactory = {
      serverResponse: serverResponse
  };
  // logging
  console.log('Factory execution');
  return appFactory;

  function serverResponse(){
    // logging
    console.log('pre-GET ' + i);
    $http.get('/endpoint/')
      .success(function(data){
        // logging
        console.log('GET is done ' + i);
        i++
        return data;
      });
  }
}

Log Ouputs:

'Factory execution'
'pre-GET 1'
'appFactory.serverReponse = undefined'
'pre-GET 1'
'server_stuff = undefined'
'GET is done 1'
'GET is done 2'

My changes:

router resolve: I chose to pass the $http function and execute later

return appFactory.server; // no paren

factory simplification:

return $http.get('/endpoint/);

controller: utilize the injected factory as the server call that it should be…

function appController( $scope, server_stuff ){
  server_stuff().success( function(data){
    // do stuff with the server info
});

Upvotes: 0

Views: 95

Answers (1)

Okazari
Okazari

Reputation: 4597

As @KevinB said working with $http call in factory should look this :

In your Factory

  function serverResponse(){
    // logging
    console.log('pre-GET ' + i);
    return $http.get('/endpoint/')
      .success(function(data){
        // logging
        console.log('GET is done ' + i);
        i++
      });
  }

In a controller :

 MyFactory.serverResponse().success(function(data){
      //your controller handling of the data.
 });

In a router resolve :

resolve: {
        server_stuff: function(appFactory){
          return appFactory.serverResponse();
        }
      }

Your router resolve will handle by itself the success of the $http call.

Upvotes: 1

Related Questions