Accessing HTTP GET JSON Properties in an Angular Controller

I use the factory method in angular.js and $ http.get to capture and process JSON data. The JSON data seems to have been successfully parsed in the factory, but I have the property of accessing the problem of this JSON data.

Here is my js code:

var app = angular.module("app", []); app.factory('mainInfo', function($http) { var obj = {content:null}; //the php will return json data below $http.get('http://localhost/test.php').success(function(response){ obj.content = response.records; }); return obj; }); app.controller('Ctrl', function($scope, mainInfo){ $scope.foo = mainInfo.content; }) ; 

Now, if I try to access foo inside the Ctrl controller, the web page will not display data:
<div ng-controller="Ctrl">Controller: {{foo}}</div>
However, if I change to $scope.foo = mainInfo in Ctrl , the web page will correctly display JSON data.

Can I find out what is the correct way to access the mainInfo.content property in the Ctrl controller?

The reason I need to access the JSON property is because I need to pre-process the data. I intend to use this data in the diagram, as in the lower controller. Currently, this controller also does not work, because I have the same problem with accessing the JSON property as in the Ctrl controller.

 app.controller("LineCtrl", function ($scope, mainInfo) { var timePoints = []; var percentagePoints = []; var i = 0; for( i = 0; i < mainInfo.content.length; i ++) { timePoints.push(mainInfo.content[i].Time); percentagePoints.push(mainInfo.content[i].Percentage); } $scope.labels = timePoints; $scope.data = percentagePoints; $scope.onClick = function (points, evt) { console.log(points, evt); }; }); 

Json data:

 { "records": [ { "Id": "1", "Time": "2015-07-25 08:00:00", "Percentage": "60" }, { "Id": "2", "Time": "2015-07-25 09:00:00", "Percentage": "70" }, { "Id": "3", "Time": "2015-07-25 10:00:00", "Percentage": "80" } ] } 

Regarding factory -controller communication, I just refer to the solution from another post: link

+7
json javascript angularjs
source share
3 answers

$ http.get returns the promise - your problem is that you return "obj" immediately and your controller is trying to access the data before the $ http.get promise is defined.

use $ http like this (no need to use $ q.defer (), as shown in another comment):

 var app = angular.module("app", []); app.factory('mainInfo', function($http) { var getRecordsPromise = $http.get('http://localhost/test.php').then(function(response){ //whatever is returned here will be accessible in the .then that is chained return response.data.records; }); return { getRecords: getRecordsPromise }; }); app.controller('Ctrl', function($scope, mainInfo){ mainInfo.getRecords.then(function (records) { $scope.foo = records; }); }) ; 
+7
source

Try this instead

 var obj = {content: []}; obj.$promise = $http.get('http://localhost/test.php').then(function(response) { angular.copy(response.data.records, obj.content); return response.data; }); return obj; 

The reason your previous method didn't work is because you re-assigned the content obj property, thereby destroying any previous links.

This is why using $scope.foo = mainInfo worked because a link to obj maintained (via mainInfo ).

Using angular.copy maintains the previous link while filling in the data.


This should take care of the links in the template, which are updated when the $http promise is resolved (due to the $http start of the digest cycle). To access data in your controller, use the $promise property

 $scope.foo = mainInfo.content; mainInfo.$promise.then(function(data) { // access data.records here }); 

Maintaining data inside your factory is a good idea if you share your factory with multiple consumers (e.g. controllers). They can reference mainInfo.content and mainInfo.$promise , and everyone will access the same dataset.

+2
source

Try the following:

 var app = angular.module("app", []); app.factory('mainInfo', function($http) { return { getData: function() { var deferred = $q.defer(); //the php will return json data below $http.get('http://localhost/test.php').success(function(response){ deferred.resolve(response.records);}); return deferred.promise; } } }); app.controller('Ctrl', function($scope, mainInfo){ mainInfo.getData().then(function(result) { $scope.foo = result.content; }); }) ; 
0
source

All Articles