Pregunta

I am trying to call a service in angular.js through a controller on load and return a promise. I then expect the promise to be fulfilled and for the DOM to be updated. This is not what happens. To be clear, I am not getting an error. The code is as follows.

app.controller('TutorialController', function ($scope, tutorialService) {
    init();
    function init() {
        $scope.tutorials = tutorialService.getTutorials();
    }
});

<div data-ng-repeat="tutorial in tutorials | orderBy:'title'">
    <div>{{tutorial.tutorialId}}+' - '+{{tutorial.title + ' - ' + tutorial.description}}</div>
</div>

var url = "http://localhost:8080/tutorial-service/tutorials";

app.service('tutorialService', function ($http, $q) {   
    this.getTutorials = function () {
        var list;
        var deffered = $q.defer();
        $http({
            url:url,
            method:'GET'        
        })
        .then(function(data){
            list = data.data;
            deffered.resolve(list);
            console.log(list[0]);
            console.log(list[1]);
            console.log(list[2]);

        });
        return deffered.promise;
    };
});

Inside of the ".then()" function in the service, I log the results and I am getting what I expected there, it just never updates the DOM. Any and all help would be appreciated.

¿Fue útil?

Solución

getTutorials returns promise by itself. So you have to do then() again.

tutorialService.getTutorials().then(function(data){
    $scope.tutorials = data;
});

Before that, $http returns a promise with success() and error().

Although you can also use then as well

Since the returned value of calling the $http function is a promise, you can also use the then method to register callbacks, and these callbacks will receive a single argument – an object representing the response.

So you are correct with that.

Otros consejos

What is your data coming from the http call look like? Your code works - I created a version of it here http://jsfiddle.net/Cq5sm/ using $timeout.

So if your list looks like:

[{ tutorialId: '1',
   title : 'the title',
   description: 'the description'
 }]

it should work

In newer Angular versions (I think v 1.2 RC3+) you have to configure angular to get the unwrap feature working (DEMO):

var app = angular.module('myapp', []).config(function ($parseProvider) {
    $parseProvider.unwrapPromises(true);
});

This allows you to directly assign the promise to the ng-repeat collection.

$scope.tutorials = tutorialService.getTutorials();

Beside that I personally prefer to do the wrapping manually:

tutorialService.getTutorials().then(function(tutorials){
    $scope.tutorials = tutorials;
});

I don't know the exact reason why they removed that feature from the default config but it looks like the angular developers prefer the second option too.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top