0

I have the next 'problem' with Angular 1.

I have this Factory that I use to get the data for the current logged user:

angular.module('myModule')
  .factory('authFactory', function ($http, $rootScope, Session, api, backend_url) {
    var authFactory = this;
    var user = {};

    authFactory.init = function(){
        // This API returns the information of the current user
        api.current_user.get({}).$promise.then(function(res){
          user = res;
        });
    }

    // I use this function to return the user
    authFactory.user = function () {
         return user;
    };
  }

This is a basic Controller example where I'm trying to access the information retrieved by the above factory:

angular.module('myModule.mypage')
.controller('PageCtrl', function ($scope, authFactory) {     
  $scope.user = authFactory.user();
  authFactory.init();

  angular.element(document).ready(function () {
      // This will return {} because it's called
      // before the factory updates user value
      console.log(authFactory.user());
      console.log($scope.user);
  });
});

The problem is that $scope.user = myFactory.user(); is not being updated once the Factory retrieve the user value.

I think my issue is related with myFactory.user();. I'm using a function, so the value returned by the function is not updated after myFactory.user has changed, I think that's why on PageCtrl the variable $scope.user is not getting any value.

My questions are:

  • Which is the best approach on my controller to wait until the user info is loaded by authFactory ?

  • Should I use a service instead ?

AlvaroAV
  • 10,335
  • 12
  • 60
  • 91

2 Answers2

1

Problem with your implementation is that user is being initialized when authFactory.init() is invoked using presumably asynchronous API.

I would suggest you to return promise from authFactory.user method.

angular.module('myModule')
.factory('authFactory', function ($http, $rootScope, Session, api, $q, backend_url) {
    var authFactory = this;
    var user = {};

    authFactory.init = function () {
        // This API returns the information of the current user
        return api.current_user.get({}).$promise.then(function (res) {
            user = res;
        });
    }

    //Return promise from the method
    authFactory.user = function () {
        var deferred = $q.defer();
        if (angular.isDefined(user)) {
            deferred.resolve(user);
        } else {
            authFactory.init().then(function () {
                deferred.resolve(user);
            });
        }
        return deferred.promise;
    };
});

Then modify controller

angular.module('myModule.mypage')
.controller('PageCtrl', function ($scope, authFactory) {
    authFactory.user().then(function (user) {
        $scope.user = user;
    })
});
Satpal
  • 132,252
  • 13
  • 159
  • 168
  • 1
    I knew where the problem was but I didn't know the best approach to solve it, with this it works like a charm. Thanks ! – AlvaroAV Nov 01 '17 at 11:01
0
angular.module('myModule')
  .factory('authFactory', function ($http, $rootScope, Session, api, backend_url) {
    var authFactory = this;

    authFactory.user = {}

    // I use this function to return the user
    authFactory.getUser() = function () {
          return api.current_user.get({}).$promise.then(function(res){
               authFactory.user = res;
          });
    };
  }


angular.module('myModule.mypage')
.controller('PageCtrl', function ($scope, authFactory) {     
  authFactory.getUser().then(function() {
       $scope.user = authFactory.user;
  });
});

Provide us a JSFiddle, I tried to help you without any testing environment.

Disfigure
  • 720
  • 6
  • 19