Home Getting asynchronous data with AngularJS
Reply: 1

Getting asynchronous data with AngularJS

MikhaelM
1#
MikhaelM Published in 2017-12-07 15:35:50Z

I am designing a company page where some page elements are loaded based on the current logged user. For example, if a company logs into my application and wants to view their account details in the dashboard, the dashboard page will load the specific elements for that company(name, description etc.). My problem is that my data does not get binded to my vm variable when I load the page. However, checking the console I see that my data is indeed being retrieved by the service, just a bit later on. Here's how I figured it out:

(function () {
'use strict';

angular.module('mainApp')
    .controller('currentCompanyCtrl',CurrentCompanyController);
CurrentCompanyController.$inject = ['CompanyService','AlertService', 'AuthService','$routeParams','$http'];
function CurrentCompanyController(CompanyService, AlertService, AuthService, $routeParams) {
    var vm = this;

    console.log(vm.company); //returns undefined
    vm.internships = getInternshipsByLoggedId();
    vm.company = getCompanyByLoggedId();
    console.log(vm); //returns two undefined objects
    for(var x in vm){
        console.log(x);
    }
    //todo find out why vm doesn't get filled earlier, probably has to do with asynchronous calls
    //do I need to return a Promise??

    //this returns the current company with the id provided by the current logged company
    //and binds it to the vm.company object
    function getCompanyByLoggedId() {
        AuthService.getCompany().then(
            function(response) {
                CompanyService.getCompanyById(response.data.id).then(
                        function success(response) {
                            vm.company = response.data;
                            console.log(response.data); //this returns the company
                        },
                        function error(response) {
                            vm.serverErrors = response.data;
                            AlertService.alertError(response.data);
                        });
            });
    }
....

The bit that appears later is the console.log that I do inside my getCompanyByLoggedId function.

This means that the data retrieval is being handled asynchronously in the service and that I should return a Promise - from that I could read/gather from Google. I tried using the $q from angular but to no avail. Do I need to modify my services? Currently they are as so:

(function () {
'use strict';

angular.module('mainApp')
    .factory('AuthService', AuthService);

AuthService.$inject = ['$http'];
function AuthService($http) {
    var service = {};

    service.getUser = getUser;
    service.getStudent = getStudent;
    service.getCompany = getCompany;

    return service;


    function getUser() {
        return $http.post('/api/user');
    }
    function getStudent() {
        return $http.post('/api/student');
    }
    function getCompany() {
        return $http.post('/api/company');
    }
}
})();

And

(function () {
'use strict';

angular.module('mainApp')
    .factory('CompanyService', CompanyService);

CompanyService.$inject = ['$http'];
function CompanyService($http) {
    var service = {};

    service.getCompanyById = getCompanyById;
    service.getById = getById;
    return service;

    function getCompanyById(id) {
        return $http.get('api/companies/'+id);
    }

    function getById(id) {
        return $http.get('api/companies/'+id+'/internships');
    }
}
})();

So basically I want to be able to bind data to my vm object so I can display it in my page. How do I do this if my data only arrives later on?

Hey24sheep
2#
Hey24sheep Reply to 2017-12-07 16:07:50Z

You have few issues here. You are not returning the value

First you could do something like this, Return and maybe you will get values. (MAYBE? Cuz sometimes there is a delay of 2-3 seconds, At least I have seen it in my case)

getCompanyByLoggedId().then((data)=>{vm.company = data});

....
//Return your promises and make a chain of it
function getCompanyByLoggedId() {
    return AuthService.getCompany().then(
        function(response) {
            return CompanyService.getCompanyById(response.data.id).then(
                    function success(response) {
                        return response.data;
                    },
                    function error(response) {
                        AlertService.alertError(response.data);
                        return response.data;
                    });
        });
}

What I do? I use $q.defer, You could read about it here https://docs.angularjs.org/api/ng/service/$q

getCompanyByLoggedId().then((data)=>{vm.company = data});
....

function getCompanyByLoggedId() {
    var defer = $q.defer();//Create a defer obj which will return when resolved or rejected
    AuthService.getCompany().then(
        function(response) {
            CompanyService.getCompanyById(response.data.id).then(
                    function success(response) {
                        defer.resolve(response.data);
                    },
                    function error(response) {
                        AlertService.alertError(response.data);
                        defer.reject(response.data);
                    });
        });
       return defer.promise;
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.301668 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO