Cannot use .then() inside ng-click function

My controller looks like this

function menuController($scope, dataService) {

    $scope.getMenuItem = '';      
    $scope.submenu = new Array();

    var setMenuItems = function (w) {
        $scope.submenu = new Array();
        $.each(w, function (i, val) {

            if ($scope.getMenuItem == 'year') {
                $scope.submenu.push( {
                    name: val[0].year, link: year

                });
            }

        });
    }
    $scope.UpdateSubmenu = function (a) {
        $scope.getMenuItem = a;

        loadData();
    };
    var loadData = function () {
        dataService.getAlbums().then(setMenuItems);
    }
    loadData();

}

when loadData() is called during initialization it works fine. However when it is called from UpdateSubmenu it fails with TypeError: dataService.getAlbums(...).then is not a function

The UpdateSubmenu funtion is activated from an ng-click event.

The dataService looks like this

(function () {
    "use strict";
    var dataService = function ($http) {
        var albums;

    var getAlbums = function () {
        if (albums)
            return albums;
        return $http.get("./api/Album").then(function (response) { albums = response.data; return albums; });
    }

    return { getAlbums: getAlbums };


}
angular.module("Main").factory("dataService", dataService);
}());

Why cant I use then() not accepted?

Answer

The issue is because you are caching the albums and returning that if it exists. The first time getAlbums() is called it returns the $http promise, the second time it returns an array of albums, which does not have a then() method.

I usually handle this by creating a promise using $q and instantly resolving it:

(function () {
    "use strict";
    var dataService = function ($http, $q) {
        var albums;

        var getAlbums = function () {

            if (albums) {
                var deferred = $q.defer();
                deferred.resolve(albums);
                return deferred.promise;
                // ... or more simply ...
                //return $q.when(albums);
            }
            else {
                return $http.get("./api/Album")
                    .then(function (response) { albums = response.data; return albums; });
            }
        }

        return { getAlbums: getAlbums };    
    }

    angular.module("Main").factory("dataService", dataService);
}());

Leave a Reply

Your email address will not be published. Required fields are marked *