4

Input: an array of username strings

Needed output: an array of Javascript Objects that correspond to each username in the input. The properties for these JS objects is to be built from two API calls for each username (I am using $.getJSON calls. Suggestions welcome).

I have an array of usernames for the Twitch API:

let users = ["OgamingSC2", "storbeck", "comster404"] // actual list is longer

I want to use the Array.prototype.map() higher order function to create an array of objects like

let userObjects = [ {...}, {...}, {...}, ... ]

where each object looks like:

{
 username: 'storbeck'   // <-- Added by me
 stream: null,          // <-- Added by first API call
 _links: {              // <-- Added by first API call
     self:'https://api.twitch.tv/kraken/streams/storbeck',
     channel:'https://api.twitch.tv/kraken/channels/storbeck'
 }
 logo: 'http:// ... png' // <-- Added by second API call
}

These are the two API call functions that return the $.getJSON Promises:

let getStreamInfo = (username) => {
  return $.getJSON('https://api.twitch.tv/kraken/streams/'+username+'?callback=?')
    .then((x) => x) // should I include this then? 
}

let getUserInfo = (twitchObject) => {
  return $.getJSON('https://api.twitch.tv/kraken/users/'+ twitchObject.user )
}

What I have so far in my code, which isn't resulting in the intended objects is:

let userObjects = users.map((user)=>{
  return getStreamInfo(user)
    .done((data) => {
      let result = {
        username: user,
        data: data
      }
      console.log(JSON.stringify(result)) // prints out the intended object so far
      return result
  })
})

Now when I print out the contents of userObjects, I get:

"{}"
"{}"
"{}"
// ... and so on

Going further, I'd like to chain userObjects and add more to each JS object from whatever I get in the getUserInfo function.

I'd like to go into how this can be done with functional Javascript, but this isn't necessary.

Kevin Hernandez
  • 522
  • 1
  • 6
  • 20
  • You're returning a `promise` from your `users.map((user))` call, not the object that's the result of the (later) corresponding ajax call. Do a standard/basic `map` from array to objects first, *then* `foreach` them into promises/ajax calls to populate the object. – freedomn-m Apr 06 '16 at 08:00

1 Answers1

0

You are on the right way, you need only small edit on your functions.

let getStreamInfo = (username) => {
  return $.getJSON('https://api.twitch.tv/kraken/streams/'+username+'?callback=?');
}

let getUserInfo = (user) => {
  return $.getJSON('https://api.twitch.tv/kraken/users/'+ user);
}

let userObjects = [];

The core function instead needs Promise synchronization:

users.map((user)=>{

  Promise.all(getStreamInfo(user), getUserInfo(user)).then((data)=>{
    let obj = {
      username: user,
      stream: data[0].stream,
      _links: data[0]._links,
      logo: data[1].logo
    }
    userObjects.push(obj);
  });
});
morels
  • 2,095
  • 17
  • 24