Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading asynchronous data in AngularJS

I'm getting a Cannot read property of undefined error when calling a function, however the data is being displayed correctly.

According to what I've read so far, that's because of asynchronous load of data made by AngularJS and that I should use promises to avoid that.

I've searched online and Angular's documentation but I didn't understand how to use it.

I'd appreciate if someone could help me.

Currently, I have the following code:

.factory('Test', ['$resource', function ($resource) {
  return $resource('data.json');
}])

.controller('MyCtrl', ['$scope', 'Test', function($scope, Test) {

Test.get(function (data) {
  $scope.myData = data;
});

$scope.myFunction = function() {
  var min = $scope.myData.min;
  var max = $scope.myData.max;
  var diff = max - min;
  return diff;
}

}])

Here's a Plunker: http://plnkr.co/edit/3AK70uVbNSdhAIIfdkHb?p=preview

like image 860
superjim Avatar asked Sep 12 '26 19:09

superjim


1 Answers

You should not use $scope.myData.min until $scope.myData is populated, which as you correctly said is asynchronous so can take a moment. The simplest solution is in this case just wrap your code into if-block:

$scope.myFunction = function() {
  if ($scope.myData) {
    var min = $scope.myData.min;
    var max = $scope.myData.max;
    var diff = max - min;
    return diff;
  }
}

myFunction is going to be checked in every digest cycle so once $scope.myData is available it the function will evaluate and return diff properly.

However, much better approach would be to work with a promise object returned by resource. In this case you could do something like this:

function myFunction(myData) {
  var min = myData.min;
  var max = myData.max;
  var diff = max - min;
  return diff;
}

Test.get().$promise.then(myFunction).then(function(data) {
  $scope.myData = data;
});

and in HTML use myData without a function:

<div ng-controller="MyCtrl">
  {{myData}}
</div>

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

like image 191
dfsq Avatar answered Sep 14 '26 08:09

dfsq