AngularJS - Factory from Controller - not getting value from $http.get

57 Views Asked by At

I have a newbie question here.

I am coding a factory in angularJS. With it I want to have a list of users, and also a method to fill it.

So this is my code ...

The factory

app.factory("usuariosFactory", function ($http) {


    var f = {};

    f.users = [];

    f.getUsers = function (callback) {
        var token = window.localStorage.getItem("_token");


        $http.get("http://localhost:8000/api/user/list?token=" + token).then(function (response) {
            f.users = response.data.users;

            /* the console.log outputs OK with the users from the server */
            console.log(f.users);
        });
    }; 

    return f;
});

The controller

app.controller("usuariosController", function ($scope, usuariosFactory) {
    var scope = this;

    /* link users from factory to controllerÅ› scope .. NOT WORKING */
    usuariosFactory.getUsers();

    scope.usuarios = usuariosFactory.users;
});

I am hitting my head to the desk right now. I dont understand how to achieve this.

2

There are 2 best solutions below

0
Sravan On BEST ANSWER

You should just return the promise from the factory to controller

Then in controller, you should subscribe to that promise and assign data to your scope variable

Factory:

app.factory("usuariosFactory", function ($http) {
    var f = {};
    f.users = [];
    f.getUsers = function (callback) {
        var token = window.localStorage.getItem("_token");
        return $http.get("http://localhost:8000/api/user/list?token=" + token);
    };
    return f;
});

Controller:

app.controller("usuariosController", function ($scope, usuariosFactory) {
    var scope = this;
    usuariosFactory.getUsers().then(function (response) {
        scope.usuarios = response.data;
    });
});
6
Alyson Maia On

The usuariosFactory.getUsers is an asynchronous function, due to $http.get inside. So, to have your data, you have to use the callback function that you've already put in the getUsers. The code should be like:

usuariosFactory.getUsers(function () {
    scope.usuarios = usuariosFactory.users;
});

and after the f.users = response.data.users; you have to call the callback function. Like this:

f.getUsers = function (callback) {
    var token = window.localStorage.getItem("_token");
    $http.get("http://localhost:8000/api/user/list?token=" + token).then(function (response) {
        f.users = response.data.users;
        callback();
    });
};

That way you will handle ansynchronous functions with a callback funtion. Another way to do this is with promises, in that way, your code should be like this:

The factory

app.factory("usuariosFactory", function ($http, $q) {
    var f = {};
    f.users = [];

    f.getUsers = function (callback) {
        var token = window.localStorage.getItem("_token");
        var deferred = $q.defer(); // Creates the object that handles the promise
        $http.get("http://localhost:8000/api/user/list?token=" + token)
            .then(function (response) {
                f.users = response.data.users;
                deferred.resolve('You can pass data!'); // Informs that the asynchronous operation have finished
            });
        return deferred.promise; // Returns a promise that something will happen later
    };

    return f;
});

The controller

app.controller("usuariosController", function ($scope, usuariosFactory) {
    var scope = this;

    // Now you can use your function just like you use $http
    // This way, you know that watever should happen in getUsers, will be avaible in the function
    usuariosFactory.getUsers()
        .then(function (data) {
            console.log(data) // Print 'You can pass data!'
            scope.usuarios = usuariosFactory.users; 
        });
});