-1

I have this code:

let channels = ["freecodecamp","test_channel","ESL_SC2"];
    channels.map(function(channel) {
      function genUrl(type, name) {
        return 'https://wind-bow.gomix.me/twitch-api/' + type + '/' + name + '?callback=?';
      }
        $.ajax({ // 2 ajax requests
          url: genUrl("streams", channel),
          dataType: 'jsonp',
          success: function(data) {
                console.log("data = ",data)
            setState(data);      
            $.ajax({
              url: genUrl("channels", channel),
              dataType: 'jsonp',
              success: function(res) { // res = result
                console.log("res = ",res)
                setState(res);
              },
            });
          },
        });
    });

but when I log, the resulting ajax isn't executing synchronously. on the map, I am expecting both ajax req to execute the same channel upon req(same index), but it's not, because the result is scrambled. let's say on the first ajax, the map is executed like ["ESL_SC2","freecodecamp","test_channel"] and on the second: ["freecodecamp","test_channel","ESL_SC2"] I want the result to be same index as it was declared?

let channels = ["freecodecamp","test_channel","ESL_SC2"];

sample of my resulted logs:

data =  {mature: false, status: "RERUN: Zest vs. data =  {mature: false, status: "RERUN: Zest vs. Trust [PvP] - Group B Elimination Map 2 - IEM Gyeonggi 2016", broadcaster_language: "en", display_name: "ESL_SC2", game: "StarCraft II", …}background: nullbanner: nullbroadcaster_language: "en"created_at: "2012-05-02T09:59:20Z"delay: nulldisplay_name: "ESL_SC2"followers: 192328game: "StarCraft II"language: "en"logo: "https://static-cdn.jtvnw.net/jtv_user_pictures/esl_sc2-profile_image-d6db9488cec97125-300x300.jpeg"mature: falsename: "esl_sc2"partner: trueprofile_banner: "https://static-cdn.jtvnw.net/jtv_user_pictures/esl_sc2-profile_banner-f8295b33d1846e75-480.jpeg"profile_banner_background_color: "#050506"status: "RERUN: Zest vs. Trust [PvP] - Group B Elimination Map 2 - IEM Gyeonggi 2016"updated_at: "2017-09-05T18:05:46Z"url: "https://www.twitch.tv/esl_sc2"video_banner: "https://static-cdn.jtvnw.net/jtv_user_pictures/esl_sc2-channel_offline_image-5a8657f8393c9d85-1920x1080.jpeg"views: 68095345_id: 30220059_links: {self: "https://api.twitch.tv/kraken/channels/esl_sc2", follows: "https://api.twitch.tv/kraken/channels/esl_sc2/follows", commercial: "https://api.twitch.tv/kraken/channels/esl_sc2/commercial", stream_key: "https://api.twitch.tv/kraken/channels/esl_sc2/stream_key", chat: "https://api.twitch.tv/kraken/chat/esl_sc2", …}__proto__: Object
 data =  {mature: false, status: "TESTING  TESTING   TESTING", broadcaster_language: null, display_name: "test_channel", game: null, …}
 data =  {mature: false, status: "Some GoLang Today #go #golang #youtube", broadcaster_language: "en", display_name: "FreeCodeCamp", game: "Creative", …}
res =  {stream: null, _links: {…}}
res =  {stream: {…}, _links: {…}}
res =  {stream: null, _links: {…}}

what I am trying to say here is like, on the first index of data let's say it's a result by "freecodecamp" as argument but on the 1st index res it's not "freecodecamp" being evaluated, it's "test_channel", so upon the execution of the map, I assume the response is long so it evaluates the next index? so in other words 1st index of data and 1st index of res is not match

gpbaculio
  • 5,693
  • 13
  • 60
  • 102
  • When you send more than one ajax request at a time asynchronously (that's what you are doing), there's no guarantee that the server will respond to them FIFO. – Kevin B Sep 05 '17 at 18:43
  • @KevinB don't know other way, but i tried async: false, as docs say it prevents firing other events from firing, but still make request. don't know what to do – gpbaculio Sep 05 '17 at 18:46
  • I don't see what your problem is to be honest. .map will send one request for each channel, followed by a second for that channel. it won't jumble them up. The problem is likely with what setState does. – Kevin B Sep 05 '17 at 18:47
  • the result is not properly indexed as i am expecting, like: "ESL_SC2" is on index 2 right? but on the result it's on 1st index, same thing happens on other items :( – gpbaculio Sep 05 '17 at 18:48
  • What index? that's the part of your question that is missing. You are likely handling the results incorrectly. – Kevin B Sep 05 '17 at 18:48
  • on the channels array – gpbaculio Sep 05 '17 at 18:49
  • You aren't doing anything with the channels array in the callbacks. I don't see what that has to do with your problem. – Kevin B Sep 05 '17 at 18:49
  • let's say on the first execution of the map, the 1st index of the channels array is being evaluated, so on the 2 ajax request, it's expected the argument channel is freecodecamp since we are on 1st execution but it's not, the last index is executed first the "ESL_SC2", and I have a hard time referencing to them – gpbaculio Sep 05 '17 at 18:52
  • you are incorrect. you are mis-interpreting the console.logs – Kevin B Sep 05 '17 at 18:52
  • 1
    You should read [this question and its answers](https://stackoverflow.com/q/750486/215552). Ajax is asynchronous, so you need to enclose your calls to it. Basically, by the time the outer Ajax's success call is made, `channel` is no longer what you think it is. – Heretic Monkey Sep 05 '17 at 18:52
  • @KevinB it's what my console logs :/ – gpbaculio Sep 05 '17 at 18:53
  • The second ajax request sent for each channel will still be the same channel that was used in the first due to the fact that you're using the `channel` param that was passed to the .map callback. – Kevin B Sep 05 '17 at 18:53
  • Add a prefix to each console.log, for example, the first ajax request, do `console.log(channel, 'data', data);` and `console.log(channel, 'res', res);` for second. the results should match the channel. – Kevin B Sep 05 '17 at 18:55
  • @MikeMcCaughan that's what I'm trying to do. can't understand why they're not in proper indexes as I am expecting they're suppose to be :( – gpbaculio Sep 05 '17 at 18:55
  • @KevinB I have done your suggestion but they are not matchiing – gpbaculio Sep 05 '17 at 18:58
  • show us the logs. what you say is happening isn't possible... – Kevin B Sep 05 '17 at 18:58
  • @KevinB i edited the question. – gpbaculio Sep 05 '17 at 19:07
  • i don't understand how those logs present your problem. What tells you the first log was from freecodecamp? Just the fact that it was first? because that's not enough, per my first comment. – Kevin B Sep 05 '17 at 19:09

2 Answers2

0

You aren't setting async to false in your ajax block. Similar to this:

How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

But in general, you shouldn't rely on synchronous ajax calls and should write in such a way that it can perform asynchronously.

Poe
  • 126
  • 6
0

I solved this using async/await and returning the result from 1st req on the 2nd req. this is the code:

$.ajax({ // 2 ajax requests
          url: genUrl("channels", channel),
          async: false,
          dataType: 'jsonp',
          success: async function(data) {
            debugger;
            $.ajax({
              url: genUrl("streams", channel),
              async: false,
              dataType: 'jsonp',
              success: async function(res) { // res = result
                debugger;
                console.log("data+res = ",{data, res})
                await setState({data, res});
              },
            });
          },
        });

I am using this in react and I think react tries to render every data resulted from the 1st ajax and so the 2nd ajax req is not evaluated as I expect but I am not sure. anyway. just try this. best of luck!

gpbaculio
  • 5,693
  • 13
  • 60
  • 102