1

Background

I've been teaching myself AngularJS this past week. I created a basic application that gets Twitch data for each Twitch channel and creates an array of "channel" objects that holds the following properties; name, logo url, streaming (yes or no), and channel url. So far I've used Angular to print each channel object by its properties to a table using the ng-repeat directive (love that feature).

Problem/ Question

I want to be able to sort the list of objects in the table whenever a user clicks the online and offline buttons thus filtering the channels by its "streaming" property. Unfortunately, I can't seem to figure out how to filter the channels by its property. Can anyone help?

HTML

  <div ng-controller="MainController" >
  <div class="container" id="test">
    <div class="row">
        <header>
            <ul id="mainMenu">
                <li class="activeMenu" ng-click="filterGo('streaming')">All</li>
                <li ng-click="filterGo('streaming')">Online</li>
                <li ng-click="filterGo('streaming')">Offline</li>
            </ul>
        </header>
        <div class="center-block" >
        <table class="table table-hover" >
            <thead>
                <tr>
                    <th class="text-center">Logo</th>
                    <th class="text-center">Channel</th>
                    <th class="text-center">Online</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="channel in twitchChannels | filter:filtered"   ng-click="setSelected();">
                    <td ><img id="size" ng-src="{{ channel.logo }}"></td>
                    <td >{{ channel.user }}</td>
                    <td >{{ channel.streaming }}</td>
                </tr>
             </tbody>
            </table>
        </div>
    </div>
  </div>

JS

var arr = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "habathcx", "RobotCaleb", "noobs2ninjas"];
var channels = [];
var count = 0;
var online = "";

// channel object 
function Channel(user, name, logo, streaming) {
    this.user = user;
    this.name = name;
    this.logo = logo;
    this.streaming = streaming;
    this.url = "https://www.twitch.tv/" + this.name;
}

var app = angular.module('myApp', []);


app.controller('MainController', function($scope, $http, $window) { 
    // loops through array of channels 
    for (var i = 0; i < arr.length; i++) {

        (function(i) { 

            $http.get("https://wind-bow.gomix.me/twitch-api/users/" + arr[i]).success(function(data) {

                var channel = data.display_name;
                var name = data.name;
                var logo = data.logo;

                $http.get("https://wind-bow.gomix.me/twitch-api/streams/" + arr[i]).success(function(json) {
                    var streaming = (json.stream === null) ? false : true;
                    if(streaming) {
                        online = "YES";
                        channels[count] = new Channel(channel, name, logo, online);
                    } else {
                        online = "NO";
                        channels[count] = new Channel(channel, name, logo, online);
                    }
                    count++;
                });
            });
         })(i);
    }

    $scope.twitchChannels = channels;

    // if channel row is clicked take user to url 
    $scope.setSelected = function() {
        $scope.selected = this.channel.url;
        $window.open($scope.selected);
    };

     // Need help here! 
     $scope.filterGo = function(x) {    
        $scope.filtered = x;
    }

});

Here is the a link for reference:http://codepen.io/bryanpleblanc/pen/jBBmgN

2
  • Please notice <> icon in editor. You can put your HTML/CSS/JS code and make it executable snippet. You can also add external resources and babel as parser(if need be) Commented Mar 10, 2017 at 8:30
  • Great suggestion! I'll do that next time! Commented Mar 11, 2017 at 0:01

2 Answers 2

1

Change your filterGo function to this

$scope.filterGo = function(x) {
        $scope.filtered = channels.filter(c => c.streaming === x);
}

and your ng-click to

<li ng-click="filterGo('YES')">Online</li>
<li ng-click="filterGo('NO')">Offline</li>

Note

You'd better use a boolean instead of YES and NO. This will be easier.

Like this

$http.get("https://wind-bow.gomix.me/twitch-api/streams/" + arr[i]).success(function(json) {
    channels[count] = new Channel(channel, name, logo, json.stream !== null);
    count++;
});

Your buttons

<li ng-click="filterGo(true)">Online</li>
<li ng-click="filterGo(false)">Offline</li>

And the filter

$scope.filterGo = function(x) {
        $scope.filtered = channels.filter(c => c.streaming);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your help. Your suggestion makes the most sense.
0

If you want to filter the objects array by one of the properties of those objects you'll need to use an object as a filter.

This should work:

<li class="activeMenu" ng-click="filterGo({streaming : undefined})">All</li>
<li ng-click="filterGo({streaming : 'YES'})">Online</li>
<li ng-click="filterGo({streaming : 'NO'})">Offline</li>

As it is now, your code is filtering the array elements that are equal to the sting streaming which is none of them because the array contains objects.

1 Comment

Thank you Titus. Well explained!

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.