1

I have a factory that request user data via an api call:

angular.module('MyApp')
    .factory('UserApi', function($auth,Account){
        return {
            getProfile: function()
                {
                 Account.getProfile()
                    .then(function(response){
                        return response.data; ----> returning json data ok!!
                    });

                }
        }   
});

But when i call the function in controller, it return me undefined

myApp.controller('AppCtrl', function($rootScope,$state,$window,$document,$scope,$filter,$resource,cfpLoadingBar,$translate,UserApi){

$scope.user = function(){
        UserApi.getProfile().then(function(data){
            $scope.currentUser = data;
        })
    }
console.log($scope.user()); ----> undefined
});

account factory:

angular.module('MyApp')
    .factory('Account', function($http){
        return {
            getProfile: function(){
                 return $http.get('/api/me');
            }
        }
    });

The error that log in console is TypeError: Cannot read property 'then' of undefined


EDIT

The only available solution is to set the response.data to $rootScope.user in which the data will be available across the controllers.

angular.module('MyApp')
    .factory('UserApi', function($auth,Account,$rootScope){
        return {
            getProfile: function()
                {
                 Account.getProfile()
                    .then(function(response){
                        $rootScope.user = response.data; ----> returning json data ok!!
                    });
                    return $rootScope.user;
                }
        }   
});
1
  • What is Account? Can you post the code for account? Commented Sep 25, 2015 at 4:36

3 Answers 3

0

First of all getProfile method should return a promise (not undefined like it's doing in your code):

angular.module('MyApp')
    .factory('UserApi', function($auth,Account){
        return {
            getProfile: function()
                {
                 return Account.getProfile()
                    .then(function(response) {
                        return response.data;
                    });
                }
        }   
});

then in controller you should use then callback:

myApp.controller('AppCtrl', function ($rootScope, $state, $window, $document, $scope, $filter, $resource, cfpLoadingBar, $translate, UserApi) {

    $scope.user = function () {
        UserApi.getProfile().then(function (data) {
            $scope.currentUser = data;
            console.log($scope.currentUser);
        })
    };
});

Also make sure you understand the difference between synchronous and asynchronous code, and why console.log($scope.user()) makes no sense in this case: response if not yet available when you try to log it. Instead you provide a callback to be called when data has come.

Sign up to request clarification or add additional context in comments.

Comments

0

You are trying to return the data after the request is completed successfully. But, since this is an ajax call we don't know when it will be completed (Basically, runs on a different thread.). There are two ways you can resolve this.

1 - Just return the call like so.

angular.module('MyApp')
    .factory('UserApi', function($auth,Account){
        return {
            getProfile: function(){
                     return Account.getProfile(); // return call and resolve in controller.                   

                }
        }   
});

2 - You can use promise ($q)

angular.module('MyApp')
    .factory('UserApi', function($auth,Account, $q){
        return {
            getProfile: function(){
                     var deferred = $q.defer();
                     Account.getProfile()
                       .success(function(data){
                           deferred.resolve(data);
                     });                   
                     return deferred.promise; // just return the promise
                }
        }   
});

and in your controller just have the following.

myApp.controller('AppCtrl', function($rootScope,$state,$window,$document,$scope,$filter,$resource,cfpLoadingBar,$translate,UserApi){

    $scope.user = function(){
        UserApi.getProfile().then(function(data){
            $scope.currentUser = data;
            console.log($scope.currentUser);
        });
    }
});

2 Comments

It still log undefined!!
console.log($scope.user()); => console.log($scope.currentUser).
0

EDITED:

You get undefined. Because:

  • there isn't return in $scope.user
  • your console.log($scope.user($scope.user()) works only initial time.
  • there is time delay for getting data from UserApi.getProfile()
  • Also, your codes have some mistakes:

I can suggest that:

  • Don't use your console.log($scope.user()) initial time.
  • Or, You should get all data initial time when factory created. Then, you use UserApi.data in your controller.(But, there is time delay. You may get success data, if request return response before from loading of your controller).

.

angular.module('MyApp')
    .factory('UserApi', function ($auth, Account) {
        var data;
        Account.getProfile().then(function (response) {
            data = response.data;
        });
        return {
            data: data
        }
    });

myApp.controller('AppCtrl', function ($rootScope, $state, $window, $document, $scope, $filter, $resource, cfpLoadingBar, $translate, UserApi) {
    console.log(UserApi.data);
});

5 Comments

How to fetch data from controller then?
Ok, I suggest other solution(i will edit my answer). I just fix your issue
@novavent. why do you need $scope.user();
Still the console log undefined
I need $scope.user so i can access them all over the controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.