-1

I am trying to create a dummy exercise to help my colleagues understand AngularJS. In my example I wish to call a service to provide an Object Array that we shall pass into a Controller and assign to a $scope variable (the example I am creating is providing information about the Beatles). I don't want to build a REST service for my examples, so I was just going to return a static / hard coded Object Array from my service. However what I return from the service is not a promise and thus I can't use the .then() method or should I say I get an error when I do try to use it.

TypeError: AlbumsService.fetchBeatlesAlbums(...).then is not a function

As we use .then() when providing data via $http I would like to use .then() so it is similar to a real world app. Is there a way I can simply get round this? Below are my controllers and my service... I have commented where the error occurs:

angular.module('beatlesApp', []) // First we state the app name, followed by an array of dependancies
    // here is our controller...
    .controller('MainCtrl', ['$scope', function($scope) {
        // here we can set our $scope variables
    }])

    .controller('ChildCtrl', ['$scope', 'AlbumsService', function($scope, AlbumsService) {
    // here we can set our $scope variables

        // HERE WE GET AN ERROR... AlbumsService.fetchBeatlesAlbums(...).then is not a function    
        AlbumsService.fetchBeatlesAlbums().then(function(resp) {
            $scope.albums = resp;
        });
    }])

// This is a service that provides data, in a real world app we would get the data from $http sources
.service('AlbumsService', function() {

    this.fetchBeatlesAlbums = function() {
        return [{
            name: 'Please Please Me',
            released: '1963',
            pic: 'please.jpg'
        }, {
            name: 'With the Beatles',
            released: '1963',
            pic: 'with.jpg'
        }, {
            name: 'A Hard Day\' s Night',
            released: '1964',
            pic: 'hard.jpg'
        }, {
            name: 'Beatles For Sale',
            released: '1964',
            pic: 'bfs.jpg'
        }, {
            name: 'Help!',
            released: '1965',
            pic: 'help.jpg'
        }, {
            name: 'Rubber Soul',
            released: '1965',
            pic: 'rubber.jpg'
        }, {
            name: 'Revolver',
            released: '1966',
            pic: 'revolver.jpg'
        }, {
            name: 'Sgt Pepper\'s Lonely Hearts Club Band',
            released: '1967',
            pic: 'splhb.jpg'
        }];
    };
});
5
  • Your fetchBeatlesAlbums returns an array. So what do you expect? Commented Feb 9, 2016 at 13:11
  • you can use $q service to return a promise and call resolve with your array of data Commented Feb 9, 2016 at 13:11
  • Well, you use $q and return a promise?! I voted -1, because your question lacks any research effort; it is easy to google how you can return a promise. Commented Feb 9, 2016 at 13:12
  • @Bergi - when I returned a function I got the same error? Commented Feb 9, 2016 at 13:12
  • @MarkSandman: You're supposed to return a promise! Commented Feb 9, 2016 at 13:54

2 Answers 2

2

This should work fine:

  .service('AlbumsService', function($q) {

    this.fetchBeatlesAlbums = function() {
        var defer = $q.defer();
        var arr = [{
            name: 'Please Please Me',
            released: '1963',
            pic: 'please.jpg'
        }, {
            name: 'With the Beatles',
            released: '1963',
            pic: 'with.jpg'
        }, {
            name: 'A Hard Day\' s Night',
            released: '1964',
            pic: 'hard.jpg'
        }, {
            name: 'Beatles For Sale',
            released: '1964',
            pic: 'bfs.jpg'
        }, {
            name: 'Help!',
            released: '1965',
            pic: 'help.jpg'
        }, {
            name: 'Rubber Soul',
            released: '1965',
            pic: 'rubber.jpg'
        }, {
            name: 'Revolver',
            released: '1966',
            pic: 'revolver.jpg'
        }, {
            name: 'Sgt Pepper\'s Lonely Hearts Club Band',
            released: '1967',
            pic: 'splhb.jpg'
        }];
        defer.resolve(arr)
        return defer.promise;
    };
});
Sign up to request clarification or add additional context in comments.

3 Comments

Correct the typo while returning promise.
sorted - thx @Diljohn5741
Better just use return $q.resolve([…])
2

You can use the $q service in combination with the $timeout service to return a promise to imitate what $http would return.

For example:

.service('AlbumsService', function($q, $timeout) {

    this.fetchBeatlesAlbums = function() {

        var deferred = $q.defer();

        $timeout(function() {
            deferred.resolve([{
                name: 'Please Please Me',
                released: '1963',
                pic: 'please.jpg'
            }, {
                name: 'With the Beatles',
                released: '1963',
                pic: 'with.jpg'
            }, {
                name: 'A Hard Day\' s Night',
                released: '1964',
                pic: 'hard.jpg'
            }, {
                name: 'Beatles For Sale',
                released: '1964',
                pic: 'bfs.jpg'
            }, {
                name: 'Help!',
                released: '1965',
                pic: 'help.jpg'
            }, {
                name: 'Rubber Soul',
                released: '1965',
                pic: 'rubber.jpg'
            }, {
                name: 'Revolver',
                released: '1966',
                pic: 'revolver.jpg'
            }, {
                name: 'Sgt Pepper\'s Lonely Hearts Club Band',
                released: '1967',
                pic: 'splhb.jpg'
            }]);
        }, 1000); //Returns after a 1 second delay.

        return deferred.promise;
    };
});

The advantage of using $timeout with $q over just $q is that you can use it imitate a realistic delay from requesting data from a real service.

3 Comments

this won't resolve. return to $timeout isn't doing anything
@charlietfl thanks, I forgot to change it to deferred.resolve, should work now.
could actually get tricky and return $timeout promise but for teaching purposes using $q would be easier to explain

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.