Search code examples
javascriptangularjsjsonpangular-resourcetwitch

AngularJS $resource - adding array element to paramDefaults


I'm using the twitch.tv api and using the Angular $resource factory. The endpoint I'm trying to use is: GET /channels/:channel. What I'm trying to do is get the channel for each array element. I tried /channels/users[1] but I know this is wrong. How can I get the :channel for all the users in the array? Or is there a better way to do this?

    (function() {
       angular.module('twitch', ['ngResource'])

       .controller('TwitchController', ['$scope', 'TwitchAPI', function($scope, TwitchAPI) {   
         $scope.getAPI = function(){
           var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];  
           for(var i = 0; i < 8; i++){
           TwitchAPI.get({channel: users.i});
         }
       }
       $scope.online = [];
       $scope.offline = [];


  }])

  .factory('TwitchAPI', function TwitchAPIFactory($resource){
     return $resource('https://api.twitch.tv/kraken/channels/:channel', { callback: "JSON_CALLBACK" });
   });
})();

Solution

  • First, you don't need to use JSONP as the Twitch API supports CORS requests, you can configure your $resource like so

    return $resource('https://api.twitch.tv/kraken/channels/:channel', {}, {
        get: {
            method: 'GET',
            headers: {
                Accept: 'application/vnd.twitchtv.v3+json',
                'Client-ID': 'Your client ID'
            }
        }
    })
    

    If you really want to use JSONP, you can't send header information in the request so it would have to look like

    return $resource('https://api.twitch.tv/kraken/channels/:channel', {
        callback: 'JSON_CALLBACK',
        api_version: 3,
        client_id: 'your client ID'
    }, {
        get: {
            method: 'JSONP'
        }
    })
    

    Doesn't look like there's a way to get more than one channel at a time (ref: https://github.com/justintv/Twitch-API/blob/master/v3_resources/channels.md) but you should be able to do so in parallel

    You can create a simple array of promises like this

    var promises = users.map(user => TwitchAPI.get({channel: user}).$promise);
    

    You can then wait for all the promises to resolve using $q.all

    $q.all(promises).then(channels => {
        angular.forEach(channels, channel => {
            // access each channel's properties here
            console.log('Channel name:', channel.display_name);
        });
    });
    

    Just don't forget to inject the $q service.