0

I have this angular controller:

app.controller('FeedCtrl', function ($scope, Profile) {
$scope.getID = function() {
    Profile.getUID()
        .then(function (data) {
            if (data !== null) {
                console.log(data.id); // returns correct id
                $scope.data = data;
            } else {
                console.log("Could not retrieve id");
            }
        }, function (error) {
            console.log(error);
        });
    console.log($scope.data); // logs: undefined

    return $scope.data; // logs: undefined
};

var somedata = $scope.getID();
console.log(somedata); //just returns undefined

});

And this Factory that the controller uses for a JSON request.

module.factory('Profile', function($http, $localStorage) {

    return {
        getUID:function(){
            return $http.get("https://graph.facebook.com/v2.2/me", {params: { access_token: $localStorage.accessToken, fields: "id,name,gender,location,website,picture,relationship_status", format: "json" }})
                .then(function(response) {
                if (typeof response.data === 'object') {
                    return response.data;
                } else {
                    // invalid response
                    return $q.reject(response.data);
                }

            }, function(response) {
                // something went wrong
                return $q.reject(response.data);
            });
        }

    };

});

The Question

I am unable to change the value of $scope.data for use outside the $scope.getID function but inside the rest of the FeedCtrl.

If you look on the comments you see what I am getting returned in the console logs.

I've tried to understand this problem by searching here in StackOverflow and Google but it seems that I don't understand the $scope concept of AngularJS.

I am grateful for any push in the right direction.

2
  • Btw; looks like you forgot to inject the `$q´ service in your factory Commented Mar 29, 2015 at 19:44
  • Just realised it after my post, and thanks for the sharp eyes and help! Commented Mar 29, 2015 at 23:11

3 Answers 3

3

That's a classic mistake, the code you're calling is asynchronous, look at your console and watch the order of your logs, the log that will return the correct id will be the last one because it will be called only after the promise has been resolved.

Is this enough of a push in the right direction for you?

A very simple example, but it's the same principle.

setTimeout(function(){
  document.write('A2: Timeout is done');
}, 5000);

document.write('A1: Called timeout, this gets logged before A2 even though my line number is higher.');
Sign up to request clarification or add additional context in comments.

1 Comment

To whoever downvoted this: could you tell me what I should change so that I can update my post if warranted?
3

That is not a scope problem, it's a time problem. You are trying to use the value before it exists.

In the controller you can only use the value after the result has arrived, i.e. in the callback for the then method. The return statement runs before there is a result, so you can't return it.

Once you have made an asynchronous call, the result has to be handled asynchronously. You can return a Future object to handle the result when it arrives, but you can never make a function that makes an asynchronous call and returns the result itself.

Comments

2

Your code is asynchronous. I wrote a response to this exact same problem in this post.

Returning after ajax call prints false

Comments

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.