jmknoll
jmknoll

Reputation: 1044

How to use callbacks correctly to consume an API in AngularJS

My problem is with consuming data from an API and modelling it effectivly before sending it over to the controller. I have a factory which gets user data from the API. The function that is giving me trouble in particular is the provideAllUserData function.

Here's my services.js

.factory('userDataService', function ($resource, settings){

        var dataService = {};

        var baseUrl = settings.baseUrl;

        dataService.getUsers = function () {
            return $resource(baseUrl + 'user').query();
        };

        dataService.getUserById = function (user) {
            return $resource(baseUrl + 'user/:id').get(
                {
                    id : user
                }
            )
        }

        dataService.provideAllUserData = function (user) {

            dataService.userData = {};
            var userData = dataService.userData;

            var updateUserData = function(callback){

                dataService.getUserById(user).$promise.then(function (res) {
                    var fetchUserData = res;
                    userData['id'] = fetchUserData.id;
                    userData['name'] = fetchUserData.name;
                    userData['quizzes'] = fetchUserData.quizzes;
                    dataService.userData = userData;
                    callback();

                });
            }

            var returnData = function() {
                //console.log(dataService.userData);
                console.log( dataService.userData)

            }
            updateUserData(returnData);
        }

    return dataService;

    })

Seems like it should be working, and if I console.log the callback, it returns the object that I want. However, when I try to log it in the controller, it returns an undefined.

Here's the relevent line from my controller.

console.log(userDataService.provideAllUserData(1));

Please let me know if I'm doing this completely wrong, or what you would do differently. I haven't used Angular for this before, so its kind of a learn-as-I-go situation.

Upvotes: 0

Views: 121

Answers (1)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

You expect asynchronous code to behave in a synchronous way.

console.log(userDataService.provideAllUserData(1));

This wouldn't work. Asynchnonicity is contageous and it'll affect the calling code too.

First, drop that callback of yours and use only promises

dataService.provideAllUserData = function (user) {

    dataService.userData = {};
    var userData = dataService.userData;

    // "then" returns a promise. Meaning, multiple thens can be chained.
    return dataService.getUserById(user).then(function (res) {
        var fetchUserData = res;
        userData['id'] = fetchUserData.id;
        userData['name'] = fetchUserData.name;
        userData['quizzes'] = fetchUserData.quizzes;
        dataService.userData = userData;

    });
  }

Then, in calling code:

userDataService.provideAllUserData(1).then(function(data) {
  console.log(data);
});

Upvotes: 2

Related Questions