Chad Johnson
Chad Johnson

Reputation: 21895

Unable to retrieve data via $http and promise with AngularJS

I'm trying to interact with my RESTful API in my AngularJS app. When I do so, no data displays in my view.

I must be misunderstanding how to use $http + promises. Any ideas what's wrong?

Here is my factory:

angular.module('mycompany.resources').factory('Forms', ['$http', '$q', function($http, $q) {
    var Forms = {};

    Forms.all = function() {
        var deferred = $q.defer();
        $http.get('/api/forms.json').then(function(response) {
            console.log(response.data);
            return response.data;
        });
        return deferred.promise;
    };

    return Forms;
}]);

and my controller:

angular.module('mycompany.admin.forms').controller('formListController', ['$scope', 'Forms', function($scope, Forms) {
    'use strict';

    $scope.forms = Forms.all();
}]);

and my template:

<div ng-controller="formListController">
    <ul class="form-list">
        <li ng-repeat="form in forms">
            <a class="form" href="#/forms/{{form._id}}">
                <span class="title">{{form.title}}</span>
                <span ng-if="form.lastPublished">Last published {{form.lastPublished | date:'M/d/yy'}}</span>
            </a>
        </li>
    </ul>
</div>

However, if I hardcode data onto the scope, I see data:

angular.module('mycompany.admin.forms').controller('formListController', ['$scope', 'Forms', function($scope, Forms) {
    'use strict';

    $scope.forms = [
        {
            "_id": "530f69046c5a65ed1b5a3809",
            "archived": false,
            "lastPublished": new Date("2014-02-20 14:21:09 UTC"),
            "title": "New Student Registration (2014 - 2015)"
        }
    ];
}]);

I understand from this example and this article that I should be able to rely on promises while fetching data in my controller via $scope.forms = Forms.all().

Upvotes: 0

Views: 935

Answers (2)

Rich
Rich

Reputation: 2885

In AngularJS 1.2 they removed the feature to automatically unwrap promises in view templates.

You can re-enable the feature with $parseProvider.unwrapPromises(true), although this will become deprecated eventually so it is better to alter your patterns.

Forms.all = function($scope, binding) {
        return $http.get('/api/forms.json').then(function(response) {
            console.log(response.data);

            $scope[binding] = response.data;

            return response.data;
        });
    };


Forms.all($scope, 'forms');

http://docs.angularjs.org/guide/migration#templates-no-longer-automatically-unwrap-promises

Edit

Looking over your factory again, you are creating an unnecessary deferred object, that also never is resolved. $http.get already returns a promise so you'd just return that. So depending on your AngularJS version you might only need to just return the result of $http.get instead of re-writing the function to bind the actual data to your scope.

Upvotes: 1

Ajay Singh Beniwal
Ajay Singh Beniwal

Reputation: 19037

I think you should simplify your source code a bit similar to below

angular.module('mycompany.resources').factory('Forms', ['$http', '$q', function($http, $q) {
    var Forms = {};

    Forms.all = function() {

      return  $http.get('/api/forms.json')

    };

    return Forms;
}]);

angular.module('mycompany.admin.forms').controller('formListController', ['$scope', 'Forms', function($scope, Forms) {
    'use strict';

     Forms.all().then(function(data){$scope.forms=data;});
}]);

Upvotes: 2

Related Questions