简体   繁体   中英

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

Your siteID variable is referenced outside of the $http.get method's scope.

Define siteID above the function like so:

app.service('SharedData', function($http) {
var siteID = '';
$http.get('config.json') 
    .success (function(data) {  
        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
    template :  template,                       
    };

return service;
})

You are not constructing objects properly. You need to define the object first, then assign values to the objects properties:

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

var service = {
    siteID :    '', // return undefined
    template :  '',                       
    };

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

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



})

I am not entirely sure you are understanding correctly how you should make use of the service in your controllers, so here is a little demo I set up:

Services Demo

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);
   })
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM