1

I'm trying to load a list of clickable news feed URLs in a dropdown-menu. When I use fixed addresses in view, it works fine but when I populate the addresses using controller, dropdown menu is fine but ng-click doesn't work as expected.

Here is jsfiddle of working version:http://jsfiddle.net/mahbub/b8Wcz/

This code works:

 <ul class="dropdown-menu">
     <li><a href="#" ng-click="feedSrc='http://www.abc.net.au/news/feed/45910/rss.xml';loadFeed($event)">ABC News</a>
     </li>
     <li><a href="#" ng-click="feedSrc='http://rss.cnn.com/rss/cnn_topstories.rss';loadFeed($event);">CNN</a>
     </li>
 </ul>

controller code:

var App = angular.module('RSSFeedApp', []);

App.controller("FeedCtrl", ['$scope', 'FeedService', function ($scope, Feed) {
    $scope.loadButonText = "Select news channel";
    $scope.loadFeed = function (e) {
        Feed.parseFeed($scope.feedSrc).then(function (res) {
            $scope.loadButonText = angular.element(e.target).text();
            $scope.feeds = res.data.responseData.feed.entries;
        });
    }


App.factory('FeedService', ['$http', function ($http) {
    return {
        parseFeed: function (url) {
            return $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=50&callback=JSON_CALLBACK&q=' + encodeURIComponent(url));
        }
    }

}]);

This code does not:

<ul class="dropdown-menu">
  <li ng-repeat =" newsChannel in channels">
  <a href="#" ng-click="feedSrc='{{newsChannel.src}}';loadFeed($event)">{{newsChannel.title}}</a>
  </li>
</ul>

controller code:

App.controller("FeedCtrl", ['$scope', 'FeedService', function ($scope, Feed) {
    $scope.loadButonText = "Select news channel";
    $scope.loadFeed = function (e) {
        Feed.parseFeed($scope.feedSrc).then(function (res) {
            $scope.loadButonText = angular.element(e.target).text();
            $scope.feeds = res.data.responseData.feed.entries;
        });
    }

$scope.channels = [
        {
            'src': 'http://www.abc.net.au/news/feed/45910/rss.xml',
            'title': 'ABC News'
        },
        {
            'src': 'http://rss.cnn.com/rss/cnn_topstories.rss',
            'title': 'CNN'
        }
    ];

}]);


App.factory('FeedService', ['$http', function ($http) {
    return {
        parseFeed: function (url) {
            return $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=50&callback=JSON_CALLBACK&q=' + encodeURIComponent(url));
        }
    }

}]);

TypeError: Cannot read property 'feed' of null

Any idea why the $scope.feedSrc doesn't get the feedSrc url?

Thanks

Ryan
  • 615
  • 8
  • 19

3 Answers3

1

So I recommend using $parent for this. ng-repeat has it's own scope so when you say "feedSrc" it is looking on the ng-repeat scope for that data. "newsChannel" is available because that gets added by ng repeat but you will notice that is never added to your parent controller's $scope.

<ul class="dropdown-menu">
  <li ng-repeat =" newsChannel in channels">
     <a href="#" ng-click="$parent.feedSrc='{{newsChannel.src}}';$parent.loadFeed($event)">{{newsChannel.title}}</a>
  </li>
</ul>

As an aside, you might consider not doing assignments in the view like that, it is generally preferable to only assign variables in the controller and make sure that your HTML is read only

njfife
  • 3,555
  • 1
  • 20
  • 31
1

The problem is how you are passing arguments to your ng-click:

ng-click="$parent.feedSrc='{{newsChannel.src}}';..."

You don't need to wrap the prperty in handlebars...

ng-click="$parent.feedSrc='newsChannel.src';..."

should fix your problem.

bluetoft
  • 5,373
  • 2
  • 23
  • 26
0

I found a workaround. Added another parameter to loadFeed method.

<ul class="dropdown-menu">
  <li ng-repeat =" newsChannel in channels">
  <a href="#" ng-click="loadFeed($event,newsChannel.src)">{{newsChannel.title}}</a>
  </li>
</ul>

and here is the controller's new version:

App.controller("FeedCtrl", ['$scope', 'FeedService', function ($scope, Feed) {
    $scope.loadButonText = "Select news channel";
    $scope.loadFeed = function (e, feedUrl) {
        Feed.parseFeed(feedUrl).then(function (res) {
            $scope.loadButonText = angular.element(e.target).text();
            $scope.feeds = res.data.responseData.feed.entries;
        });
    }
    $scope.channels = [
        {
            'src': 'http://www.abc.net.au/news/feed/45910/rss.xml',
            'title': 'ABC News'
        },
        {
            'src': 'http://rss.cnn.com/rss/cnn_topstories.rss',
            'title': 'CNN'
        }
    ];

}]);

thanks to this post: ng-click inside ng-repeat

Community
  • 1
  • 1
Ryan
  • 615
  • 8
  • 19