0

I need to get feed using $http.jsonp after that I return deferred.resolve(feed) which should pass feed value to chained function EntryStateUrlService.getEntryStateUrl.

For some reason it says FeedService.parseFeed(feedSrc) evaluated as undefined therefore then() method cannot be invoked on undefined. How to fix it?

app.service('LoadData', ['FeedService', 'EntryStateUrlService', '$q', function(FeedService, EntryStateUrlService, $q) {
    var deferred = $q.defer();

    this.loadData = function(feedSrc) {

        FeedService.parseFeed(feedSrc).then(EntryStateUrlService.getEntryStateUrl).then(function(urls) {
            $rootScope.links = urls;
        });
    }
}]); //TypeError: undefined is not a function

app.service('FeedService', function($http, $q) {
    var deferred = $q.defer();

    this.parseFeed = function(url) {
        $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=JSON_CALLBACK&q=' + encodeURIComponent(url))
            .success(function(res) {

                deferred.resolve(res.data.responseData.feed.entries); //TypeError: Cannot read property 'responseData' of undefined
            }).error(function() {
                deferred.reject();
            });
 return deferred.promise(); //TypeError: object is not a function
    }
});
app.service('EntryStateUrlService', ['$state', '$q', function($state, $q) {
    var deferred = $q.defer();
    this.getEntryStateUrl = function(feeds) {
            var idx = 0;
            feeds.forEach(function(e) {
                $http.jsonp(e.link).success(function(data) {
                    /*stuff*/
                    deferred.resolve('root.' + generatedStateName);
                });
            }); //forEach
        } //getEntryStateUrl
return deferred.promise();
}]); //EntryStateUrlService

UPDATE

After adding return deferred.promise(); both to EntryStateUrlService and FeedService I am getting TypeError: object is not a function for return deferred.promise(); in FeedService.

J.Olufsen
  • 13,415
  • 44
  • 120
  • 185

3 Answers3

1

In the FeedService return the deferred.promise, Also in the EntryStateUrlService, invoking the multiple service in the forEach, hence if the promise needs to be resolved once all the service completed, use $q.all as like below.

app.service('LoadData', ['FeedService', 'EntryStateUrlService', '$q', function(FeedService, EntryStateUrlService, $q) {
    this.loadData = function(feedSrc) {

        FeedService.parseFeed(feedSrc).then(EntryStateUrlService.getEntryStateUrl).then(function(urls) {
            $rootScope.links = urls;
        }, function(failureException) {
            // failure error handler comes here.        
        });
    }
}]); //TypeError: undefined is not a function

app.service('FeedService', function($http, $q) {

    this.parseFeed = function(url) {
        var deferred = $q.defer();
        $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=JSON_CALLBACK&q=' + encodeURIComponent(url))
            .success(function(res) {

                deferred.resolve(res.data.responseData.feed.entries); //TypeError: Cannot read property 'responseData' of undefined
            }).error(function() {
                deferred.reject();
            });
        return deferred.promise;
    }
});
app.service('EntryStateUrlService', ['$state', '$q', function($state, $q) {

    this.getEntryStateUrl = function(feeds) {

            var deferred = $q.defer();
            var idx = 0, promises = [];
            feeds.forEach(function(e) {
                $http.jsonp(e.link).success(function(data) {
                    /*stuff*/                    
                });
            }); //forEach

            // once all the jsonp service in the  for loop is finished, then resolve the promise
            $q.all(promises).then(function() {
                deferred.resolve('root.' + generatedStateName);
            }, deferred.reject);

            return deferred.promise;

        } //getEntryStateUrl
}]); //EntryStateUrlService
  • One of my promises during `feeds.forEach` cycle ends up with error. Maybe because this in `LoadData` never executes line `$rootScope.links = urls;` which is inside `then`. How to fix it? – J.Olufsen Feb 04 '15 at 15:18
  • yes. since we are using $q.foreach, if any of the feeds.forEachEnds up in failure, it will not execute the then success callback, instead it will execute the failure call. updated code to handle the failure condition. – Karthik Easwaran Feb 05 '15 at 06:30
0

Shouldn't you parseFeed function be returning the deferred?

this.parseFeed = function(url) {
    $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=JSON_CALLBACK&q=' + encodeURIComponent(url))
        .success(function(res) {

            deferred.resolve(res.data.responseData.feed.entries);
        }).error(function() {
            deferred.reject();
        });
    return deferred;
}
Chris Charles
  • 4,406
  • 17
  • 31
  • I added `return deferred;` but same 2 errors persist: `TypeError: Cannot read property 'responseData' of undefined` and `TypeError: undefined is not a function`, see code update.... – J.Olufsen Feb 04 '15 at 13:06
  • have you also added the return to EntryStateUrlService? – Chris Charles Feb 04 '15 at 13:10
0

I'am missing a promise in your code. I think you have to return a promise inside your FeedService: return deferred.promise(); instead of return deferred;

dec
  • 594
  • 1
  • 9
  • 18