Get data from $resource response in angular factor

2019-06-23 19:24发布

I have this factory:

.factory("Member", function($resource) {
    var endpoint = "http://some valid url";

    function generateMemberToken (id1, id2) {
        return $resource(endpoint, null, {
            query: {
                method: 'GET',
                headers: {
                    'id1': id1,
                    'id2': id2
                }
            }
        })
    }

    var member = {
        generateMemberToken : generateMemberToken
    }

    return member;
})

and this controller:

 .controller('memberKeyCtrl', function($scope, Member){

    $scope.generateMemberToken = function () {
        $scope.member = Member.generateMemberToken('123456789', '789456123').query();
        console.log($scope.member);
        console.log($scope.member.someProperty); // problem here
    }

$scope.member is a JSON response from an API, i.e.

 {firstName:Joe, lastName:smith}

I can see my ouput in the console for "$scope.member" and it has the property im looking for here, referred to as .someProperty. I just cannot seem to extract that data as i have it here, see the "//problem here" line in the controller.

My guess is that I somehow set up my factory incorrectly or am not making the property somehow available outside of the factory. New to angular so having some trouble understanding this.

Please let me know if any additional info is needed.

1条回答
三岁会撩人
2楼-- · 2019-06-23 19:47

The issue here is with the Async nature of $resource, and how the console interacts with your data.

.query() is an asynchronous call, which means that it does not return a value immediately; instead it allows the code to continue to flow. Your next statement is to console.log($scope.member);, which doesn't immediately expand $scope.member to see it's properties until they are used or inspected. The next call is to console.log($scope.member.someProperty);, which would expand $scope.member in order to find someProperty. Since the callback to your .query() hasn't returned yet, this is going to log undefined. By the time you go to check to see what is in the first console.log, the callback has completed, and so the object appears as though it had all the properties all along, even though it didn't really, at the time they were attempted to be accessed.

The simple way to handle this is to wrap the calls in .then(), to ensure that you aren't executing them until after the promise from .query() has returned. In order to chain .then(), you need to access the promise returned, i.e.

$scope.generateMemberToken = function () {
    $scope.member = Member.generateMemberToken('123456789', '789456123')
    .query().$promise.then(function(){
        console.log($scope.member);
        console.log($scope.member.someProperty); // problem here
    });
};

The .query() function syntax allows for an anonymous callback, that will allow you to pass a function that should be executed when the query() is complete, rather than chaining .then() statements. For example:

 $scope.generateMemberToken = function () {
    $scope.member = Member.generateMemberToken('123456789', '789456123')
    .query({}, function() {
        console.log($scope.member);
        console.log($scope.member.someProperty); // problem here
    });
}
查看更多
登录 后发表回答