Angularjs $ http.get () and then list binding

I have a list that looks like this:

<li ng-repeat="document in DisplayDocuments()" ng-class="IsFiltered(document.Filtered)"> <span><input type="checkbox" name="docChecked" id="doc_{{document.Id}}" ng-model="document.Filtered" /></span> <span>{{document.Name}}</span> </li> 

I bind this list in my controller so that:

 $scope.Documents = $http.get('/Documents/DocumentsList/' + caseId).then(function(result) { return result.data; }); 

When this is done, I get no results. when I remove the then method, I get three blank lines, making the number OK, but the information is not displayed.

I know that "everthing" else works, since I previously populated the list with jQuery, what am I doing wrong?

Here is the response from the server:

 {Id:3f597acf-a026-45c5-8508-bc2383bc8c12, Name:ZZ_BL0164_Skisse BL0164_945111.pdf, Order:1,…} {Id:46f51f1f-02eb-449a-9824-8633e8ae7f31, Name:ZB_BL0201_Firmaattest BL0201_945111.pdf, Order:1,…} {Id:fddd1979-c917-4b32-9b83-b315f66984ed, Name:ZA_BL0228_Legitimasjonsskjema BL0228_945111.pdf,…} 
+47
angularjs promise get
May 31 '13 at 11:05
source share
4 answers

The $ http methods return a promise that cannot be repeated, so you need to attach the results to the scope variable via callbacks:

 $scope.documents = []; $http.get('/Documents/DocumentsList/' + caseId) .then(function(result) { $scope.documents = result.data; }); 

Now, since this defines the documents variable only after receiving the results, you must first initialize the documents variable in the scope: $scope.documents = [] . Otherwise, your ng-repeat will suffocate.

Thus, ng-repeat will first return an empty list, because the documents array is empty at first, but as soon as the results are obtained, ng-repeat will start again because the β€œdocuments” were changed into a successful callback.

Alternatively, you can change the ng-repeat expression to:

 <li ng-repeat="document in documents" ng-class="IsFiltered(document.Filtered)"> 

because if your DisplayDocuments() function makes a call to the server, that call will be executed many times, due to $ digest loops.

+51
May 31 '13 at 11:26
source

A promise returned from $http cannot be linked directly (I don’t know exactly why). I use a wrapping service that works great for me:

 .factory('DocumentsList', function($http, $q){ var d = $q.defer(); $http.get('/DocumentsList').success(function(data){ d.resolve(data); }); return d.promise; }); 

and bind it to the controller:

 function Ctrl($scope, DocumentsList) { $scope.Documents = DocumentsList; ... } 

UPDATE:

Angular has removed 1.2 auto-deploy promises. See http://docs.angularjs.org/guide/migration#templates-no-longer-automatically-unwrap-promises

+25
Aug 13 '13 at 20:26
source

In fact, you get a promise on $http.get .

Try using the following thread:

 <li ng-repeat="document in documents" ng-class="IsFiltered(document.Filtered)"> <span><input type="checkbox" name="docChecked" id="doc_{{document.Id}}" ng-model="document.Filtered" /></span> <span>{{document.Name}}</span> </li> 

Where documents is your array.

 $scope.documents = []; $http.get('/Documents/DocumentsList/' + caseId).then(function(result) { result.data.forEach(function(val, i) { $scope.documents.push(/* put data here*/); }); }, function(error) { alert(error.message); }); 
+6
May 31, '13 at 11:30
source

Try using the success() callback

 $http.get('/Documents/DocumentsList/' + caseId).success(function (result) { $scope.Documents = result; }); 

But now, since Documents is an array, not a promise, remove ()

 <li ng-repeat="document in Documents" ng-class="IsFiltered(document.Filtered)"> <span> <input type="checkbox" name="docChecked" id="doc_{{document.Id}}" ng-model="document.Filtered" /> </span> <span>{{document.Name}}</span> </li> 
+1
May 31 '13 at 11:17
source



All Articles