0

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.

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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.

2 Comments

I guess because it becomes transparent that usage of then indicates a promise was returned from underlying call. I prefer it as well. :)
That may indeed be the reason, it's also one of the reasons why I prefer wrapping it myself. Another one of course is that I've configured restangular to always give me the complete repsonse including headers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.