using data from a promise in an angular controller

109 Views Asked by At

Inside of my controller I am calling my service that contains an array of data that I would like to work with in DrinkLibrary.DrinkLibrary has a getDrinks-method that is getting the data from my database.

app.controller('analysisController',function(Drink,DrinkLibrary,$scope){
    console.log('connected');

    var drinkSet = function(){
        DrinkLibrary.getDrinks().success(function(data){
            var caffeineData = data;
        });
    };
    drinkSet();
});

When I call success() I am getting the data that I want inside of caffeineData. When I call drinkSet() I am getting the data that I need inside of my browser console. In the controller. However, I am limited to caffeineData exist inside of the drinkSet-method.

Is there a better way to set this up so that I might be able to use this data in a chart?

4

There are 4 best solutions below

2
On BEST ANSWER

Where do you want the data to be available? There are a number of things you can do. For example:

app.controller('analysisController',function(Drink,DrinkLibrary,$rootScope,$scope){
    console.log('connected');

    var drinkSet = function(){
        DrinkLibrary.getDrinks().success(function(data){
            var caffeineData = data; // local only to this function
            $scope.caffeineData = data; // local to this controller
            $rootScope.caffeineData = data; // local to the application
        });
    };
    drinkSet();
});

References:

https://docs.angularjs.org/guide/scope

https://docs.angularjs.org/api/ng/service/$rootScope

1
On

Since caffeineData is a local variable so it will not be available in the view. You have to set the data to a $scope then you can access it in your view.

app.controller('analysisController',function(Drink,DrinkLibrary,$scope){
    console.log('connected');

    var drinkSet = function(){
        DrinkLibrary.getDrinks().success(function(data){
            $scope.caffeineData = data;
        });
    };
    drinkSet();
});

Inside the view. Based on the object type of caffeineData you can add your logic in the view.

<div>{{caffeineData}}</div>

You can learn more about angular scope here https://docs.angularjs.org/guide/scope

Demo http://plnkr.co/edit/s8mWpCTV6bvxmR3hOLOM?p=preview

0
On

You can bind the data to the controller $scope and use it in your html

app.controller('analysisController',function(Drink,DrinkLibrary,$scope){
   console.log('connected');

   var loadDrinks = function(){
     DrinkLibrary.getDrinks().success(function(data){
        $scope.caffeineData = data;
     });
    };
   loadDrinks();
});

HTML

<ul ng-controller="analysisController">
    <li ng-repeat="drink in caffeineData">
       <label ng-bind="drink.name"></label>
    </li>
</ul>
2
On

If you need to use the response data outside that function, try instantiating a variable first, before defining your drinkSet function. Assuming your data to be set into caffeineData is an array, like this:

app.controller('analysisController',function(Drink,DrinkLibrary,$scope){
  console.log('connected');

  var caffeineData = []; // could also set via $scope.caffeineData
  var drinkSet = function(){
      DrinkLibrary.getDrinks().success(function(data){
          caffeineData = data;
      });
  };
  drinkSet();
});

By instantiating it outside the function, it won't be kept private to the function (JS has function level scope for variables). The benefit here is that if anything is set to build in the DOM from yoru caffeineData var, you can have it build correctly over an empty array, before it populates.

There's one more improvement we can make to your controller here, assuming nothing else happens inside your success callback, other than set the data; have a look:

app.controller('analysisController',function(Drink,DrinkLibrary,$scope){
  console.log('connected');

  var caffeineData = []; // could also set via $scope.caffeineData
  DrinkLibrary.getDrinks().success(function(data){
      caffeineData = data;
  });
});

As to your wanting to use this data in a chart, you could define your chart initiation call inside the success callback, to only invoke the chart building function on successful setting of your data.


[Edit] Per my comment, here's an updated version I suggest you try. You'll note I put the console.log inside the success/error callbacks, to ensure your dump to the console is after the promise has resolved, either way. I've included the comments and additional callback parameters as shown in the $http.get example from the AngularJS docs, in which the comments talk specifically about the async nature of promises.

app.controller('analysisController',function(Drink,DrinkLibrary,$scope){
  console.log('connected');

  $scope.caffeineData = []; // could also set via $scope.caffeineData
  DrinkLibrary.getDrinks()
      .success(function(data, status, headers, config){
          // this callback will be called asynchronously
          // when the response is available
          $scope.caffeineData = data;
          console.log("Response code of the GET was: "+status);
          console.log("Data received: "+data);
      }).error(function(data, status, headers, config) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
        $scope.caffeineData = null; //no data :'-(
        console.log("data: " + data);
        console.log("status: " + status);
        //console.log("headers: " + headers);
        //console.log("config: " + JSON.parse(config));
      });
});

[/Edit]