1

I'm new to AngularJS and still stuck at the basics.

I'm creating a service with a $http.get to load a couple of Json files. When I load the service into the controller I get empty arrays.

This is my service

app.service('productService', ['$http', function($http){
    var lista = this;
    lista.products = [];
    lista.menu = [];

    $http.get('/prodotti_1.json').success(function(data){
        lista.products = data;
    });

    $http.get('/menu_1.json').success(function(data){
        lista.menu = data;
    });
}]);

And this is my controller:

app.controller('ProductController', ['productService', function(productService){
    console.log(productService.products);
    console.log(productService.menu);
}]);

The console prints just an empty Array [ ]. If I put the console.log(data) inside the success promise, the console.log prints the array just fine. I thought from codeschool it could be easier, but I guess I'm missing a point to pass the data from the success promise to the controller. In many other situations I see the usage of $scope variable, but I learnt that I can also avoid the use if I use "this". So that's my code doesn't display any $scope.

I'm using Angular 1.4.1 FYI and I saw many forums and other questions but it seems a different situation.

Thank you

2
  • The problem is that you load your data asynchronous. I.e. your list are not assigned when calling the console.log function. $http.get does not block until the data is available. Commented Jul 3, 2015 at 14:44
  • your are only missing the $q promise concept: promises are asynch, so if you put console.log inside controller initialization you will print only the initial value, create a binding or a watcher and check that values are set Commented Jul 3, 2015 at 14:44

1 Answer 1

1

You are accessing the variables before the promise is resolved. What you can do is return an object that has your various promises as property.

app.service('productService', ['$http', function($http){
    return {
         request1: $http.get('/prodotti_1.json'),
         request2: $http.get('/menu_1.json')
       }
}]);

So you can handle it in your controller.

app.controller('ProductController', ['productService', function(productService){
    productService.request1.success(function(data){
        //access the data
    });

    productService.request2.success(function(data){
        //access the data
    });
}]);

Hope it helps.

Sign up to request clarification or add additional context in comments.

5 Comments

This saved my day, it works! May I ask you to explain more theory about my wrong method? You said "You are accessing the variables before the promise is resolved", you mean from the controller? I thought that when a service is loaded inside a controller it's somehow "ready" including its properties or methods...in the way you corrected my code, it seems more the service is like a function to call
Another question. I need to make all my code inside the success promise? infact if inside the success I put "lista.products = data;" and outside the promise I write console.log(lista.products); I have again the same original issue, so what I'm not understanding? @Pravin
well when you inject the service its just injecting it. And when you call the service in your console, it goes to the service, instantiates the properties product and menu and makes two asynchronous requests and returns. At this point the http request is still waiting for the promise to be resolved as a success or failure. The console.log() logs the present value of lista.products and lista.menu. Hence it logs the empty array. To access the variables after the promise is resolved, you have to access it from within the callback which is called after you get a response.
Thank you very much! so what I was doing was like trying to print a response that's not yet arrived, so it just prints what console.log had there ready, so the empty array.
yes you should do it inside your success. If you want to display the data somewhere, you can instantiate a global variable, $scope.someVar={}, before the http call and you might want to display that data somewhere on html. Now when the response comes from server, assign this $scope.someVar to ur returned data, and your DOM updates due to two way binding. I dont know your particular use case, but this is one...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.