Search code examples
javascriptangularjsangularjs-service

Angular services issue


I need some help to understand what is wrong in the following angular service code.

EDIT: I have few controllers in different js files that use CRUD API like

$http.get('/api/sites/' + service.siteID)

or simply need variables directive like

templateUrl: '../../' + service.template + ' + '.html'

So I create a service to share those variables between all js file instead of making api call in each file.

Here is the service

app.service('SharedData', function($http) {

$http.get('config.json') 
    .success (function(data) {  
        var siteID = data._id;
        console.log(siteID); // return 553e2d15f91e4bd75d000008

         $http.get('/api/sites/' + siteID)
            .success(function(site) {
                var template = site.template;
                console.log(template); // return myTemplate
            })
            .error(function(data) {
                console.log('Error: ' + data);
            })
    })
    .error(function(data) {
        console.log('Error: ' + data);
    })

service = {
    siteID :    siteID, // return undefined instead of 553e2d15f91e4bd75d000008
    template :  template // return undefined instead of myTemplate                      
    };

return service;
})

I just want to make a precision. If I write my service like below, it works fine, I mean the value are well passed in all controllers and directives

app.service('SharedData', function() {
service = {
    siteID : '553e2d15f91e4bd75d000008',
    pageID : '553e2d15f91e4bd75d000009',
    template : 'template1',
    layout : 'home'
    };

return service;
})

Many Thanks

EDIT

I have change the service as follow

app.factory('SharedData', function($http) {
service = {};
$http.get('config.json') 
    .success (function(data) {  
        service.siteId = data._id; 
        //console.log(service.siteId);

        $http.get('/api/sites/' + service.siteId)
            .success(function(site) {
                service.template = site.template;
                //console.log(service.template);
            })
    })
service.pageID = '553e2d15f91e4bd75d000009';
service.layout = 'home'
return service
})

In the controller console.log(service) return an object with all value :

layout: "home"
pageID: "553e2d15f91e4bd75d000009"
siteId: "553e2d15f91e4bd75d000008"
template: "template1"

console.log('Layout is ' + service.layout); // return home
console.log('PageID is ' + service.pageID); // return 553e2d15f91e4bd75d000009

but

console.log('siteID is ' + service.siteId); // return undefined  !!!!!
console.log('template is ' + service.template); // return undefined !!!!!

DO NOT UNDERSTAND PLEASE HELP


Solution

  • I get this help from Google Group

    "You are getting your information asynchronous. Simply said, the information is not yet available on the moment you are logging them out. Only when the $http calls are 'done' you will have the information available in your controller. In the debugger screen, service is an 'live' object, so it gets updated. the data is not an object (at that point) and is logged as such. Have a look at the $q service on how promises work in angular."

    Then here is how to fix the issue with $q

    service = {};
        app.service('GetSiteID', function ($http) {
            return $http.get('config.json') 
            .then (function(response) { 
                service.siteID = response.data._id
                return service.siteID
       });
    })  
    app.service('GetTemplateAndPages', function (GetSiteID, $http, $q) {
        return GetSiteID
            .then(function(id) {
            return $http.get('/api/sites/' + id)
                .then (function(response) {
                    var data = response.data;
                    service.template = response.data.template;
                    service.pages = response.data.pages;
                    return service.template;
                    return service.pages
           })
        })
    })  
    app.service('SharedData', function (GetSiteID, GetTemplateAndPages, $q) {
        return $q.all([GetSiteID, GetTemplateAndPages]) 
            .then (function(response) {
             return service
        })
    })
    

    then use it in controller like

    app.controller('pagesController', function(SharedData, $scope, $http) {
        SharedData.then(function(service) {
          console.log(service);
          console.log('Site ID is ' + service.siteID); 
          console.log('Template is ' + service.template);
          console.log('Pages are ' + service.pages);
       })
    });