0

I am just starting out in Angular, and I have been stuck for some time on an issue.

My factory is properly creating an array containing objects, RSS feed data, and will load to the console. The issue is that I cannot seem to get the array to return to the controller.

Any help would be appreciated. Please pardon the rough and sloppy code.

Main.js

function FeedCtrl($scope, GetFeed) {

    $scope.itemId = 0;
    //$scope.items = [];

    console.log('Get episodes in ctrl');
    $scope.items = function() {
        return GetFeed.getEpisodes();
    };
    console.log('display items from ctrl');
    console.log($scope.items());

  $scope.itemId = function(index) {
    $scope.itemId = index;
    console.log($scope.itemId);
    console.log($scope.itemNames[$scope.itemId].title);
  };

};

function EpisodeCrtl($scope, GetFeed) {
    //getFeed.pullFeed();
};

function GetFeed($http){

var episodeArray = [];

function items(){
   console.log('Firing pullFeed');
return $http.get('assets/feed.xml').then(function(response) {
    var x2js = new X2JS()
    var itemDef = x2js.xml_str2json(response.data);
    itemsObj = itemDef.rss.channel.item;

    var numOfItems = itemsObj.length;
    episodeArray.length = 0;
    for (var i = 0; i < numOfItems; i++) {
      episodeArray.push({
        title: itemsObj[i].title,
        link: itemsObj[i].link,
        author: itemsObj[i].author,
        pubDate: new Date(itemsObj[i].pubDate),
        summary: itemsObj[i].summary,
        duration: itemsObj[i].duration,
        description: itemsObj[i].description
      });
    }

    console.log(episodeArray);
    return episodeArray; 
  })
 };

 return {
    getEpisodes: function(){
      console.log(episodeArray);
      episodeArray.length = 0;
      items();
      console.log(episodeArray);
      return(episodeArray);
    }
 }
};

var app = angular.module('ctApp', ['ngMaterial', 'ngAnimate', 'ngRoute'])
.config(function($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'list.html',
            controller: 'FeedCtrl'
        })
        .when('/about', {
            templateUrl: 'about.html',
           controller: 'EpisodeCrtl'
        });
})
.config( [ '$compileProvider', function( $compileProvider ) {
        var currentImgSrcSanitizationWhitelist = $compileProvider.imgSrcSanitizationWhitelist();
        var newImgSrcSanitizationWhiteList = currentImgSrcSanitizationWhitelist.toString().slice(0,-1)
        + '|chrome-extension:'
        +currentImgSrcSanitizationWhitelist.toString().slice(-1);
    }
])
.factory('GetFeed', GetFeed)
.controller('FeedCtrl', FeedCtrl)
.controller('EpisodeCrtl', EpisodeCrtl);

1 Answer 1

1

You need to understand how async calls and promises work. You seem to be doing things correctly at first - you are doing return on an $http.get call - this returns the promise. You are doing return on episodeArray within the .then handler. This is correct.

But, then, in the following function definition:

getEpisodes: function(){
      console.log(episodeArray);
      episodeArray.length = 0;
      items(); // this returns immediately and does not yet have the data
      console.log(episodeArray);
      return(episodeArray);
})

The call to items returns immediately. episodeArray is still empty. You return the empty array object [].

So, you need to return items() - this will return the same promise that $http.get().then() is making.

getEpisodes: function(){
      return items();
})

Then you can't just assign the return value to $scope.items - in the current code it just assigns that same empty array []. And clearly, if a promise is returned - this is not what you need. Instead, you have to .then it in the controller, and assign the value there:

GetFeed.getEpisodes().then(function(episodeArray){
   $scope.items = episodeArray;
})
Sign up to request clarification or add additional context in comments.

4 Comments

thanks so much for the assist. I modified the code and I am trying to understand it. Currently with your changes it is still not working. Updating the code to reflect changes on post.
@tnotm, Don't edit the original question - otherwise, both the question and answer would not make sense to someone else. (I reverted the changes) If you need further help, replicate the issue in a plunker
Here's your forked plunker with all the xml parsing removed - plnkr.co/edit/ssDph9gyHyQDQVVDbdbf?p=preview
thanks so much. I still have to digest this some, but I think I understand it. I will work on modifying the data after the call and push to the controller... or maybe inside another service. Also I will be reading up on async and promises. Thanks again.

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.