Cannot push item to array with map() and async-await












0















I'm making a discord bot to play youtube video. I'm using this google API to get the video titles from their IDs but the get_title() function returns an empty jsons array.



I've tried to log the jsons array right after the request() function and right after the map() function but they both return empty arrays. If i console.log(jsons) right after jsons.push(json) , it does return arrays with titles.



const browser = require('https')
var urls = ['https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=QKm4q6kZK7E', 'https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=ib3fDx75Esw']

function get_title() {
return new Promise(function(resolve, reject) {
var jsons =
urls.map(url => {
browser.request(url, res => {
let body = ''
res.on('data', data => {
body += data
})
res.on('end', () => {
var json = JSON.parse(body).items[0].snippet.title
jsons.push(json)
})
}).end()
})
resolve(jsons)

})
}
async function main() {
res = await get_title()
console.log(res)
}
main()


I expect the output to be like this




[ 'Santa Tracker: Making a penguin-proof password','Google Duo: Stay in touch after the Holidays' ]











share|improve this question

























  • You are returning jsons before you receive any response for your API calls. The data is pushed to jsons, but the result has already been returned.

    – Sachin Gupta
    Dec 28 '18 at 20:02











  • @SachinGupta i've just edited the code. I tried using promise but resolve didnt work too.

    – Minh Doan
    Dec 28 '18 at 20:14
















0















I'm making a discord bot to play youtube video. I'm using this google API to get the video titles from their IDs but the get_title() function returns an empty jsons array.



I've tried to log the jsons array right after the request() function and right after the map() function but they both return empty arrays. If i console.log(jsons) right after jsons.push(json) , it does return arrays with titles.



const browser = require('https')
var urls = ['https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=QKm4q6kZK7E', 'https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=ib3fDx75Esw']

function get_title() {
return new Promise(function(resolve, reject) {
var jsons =
urls.map(url => {
browser.request(url, res => {
let body = ''
res.on('data', data => {
body += data
})
res.on('end', () => {
var json = JSON.parse(body).items[0].snippet.title
jsons.push(json)
})
}).end()
})
resolve(jsons)

})
}
async function main() {
res = await get_title()
console.log(res)
}
main()


I expect the output to be like this




[ 'Santa Tracker: Making a penguin-proof password','Google Duo: Stay in touch after the Holidays' ]











share|improve this question

























  • You are returning jsons before you receive any response for your API calls. The data is pushed to jsons, but the result has already been returned.

    – Sachin Gupta
    Dec 28 '18 at 20:02











  • @SachinGupta i've just edited the code. I tried using promise but resolve didnt work too.

    – Minh Doan
    Dec 28 '18 at 20:14














0












0








0








I'm making a discord bot to play youtube video. I'm using this google API to get the video titles from their IDs but the get_title() function returns an empty jsons array.



I've tried to log the jsons array right after the request() function and right after the map() function but they both return empty arrays. If i console.log(jsons) right after jsons.push(json) , it does return arrays with titles.



const browser = require('https')
var urls = ['https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=QKm4q6kZK7E', 'https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=ib3fDx75Esw']

function get_title() {
return new Promise(function(resolve, reject) {
var jsons =
urls.map(url => {
browser.request(url, res => {
let body = ''
res.on('data', data => {
body += data
})
res.on('end', () => {
var json = JSON.parse(body).items[0].snippet.title
jsons.push(json)
})
}).end()
})
resolve(jsons)

})
}
async function main() {
res = await get_title()
console.log(res)
}
main()


I expect the output to be like this




[ 'Santa Tracker: Making a penguin-proof password','Google Duo: Stay in touch after the Holidays' ]











share|improve this question
















I'm making a discord bot to play youtube video. I'm using this google API to get the video titles from their IDs but the get_title() function returns an empty jsons array.



I've tried to log the jsons array right after the request() function and right after the map() function but they both return empty arrays. If i console.log(jsons) right after jsons.push(json) , it does return arrays with titles.



const browser = require('https')
var urls = ['https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=QKm4q6kZK7E', 'https://www.googleapis.com/youtube/v3/videos?key=AIzaSyC7udvST-lyLpx_gxHBc22kGYhEUOeQz5k&part=snippet&id=ib3fDx75Esw']

function get_title() {
return new Promise(function(resolve, reject) {
var jsons =
urls.map(url => {
browser.request(url, res => {
let body = ''
res.on('data', data => {
body += data
})
res.on('end', () => {
var json = JSON.parse(body).items[0].snippet.title
jsons.push(json)
})
}).end()
})
resolve(jsons)

})
}
async function main() {
res = await get_title()
console.log(res)
}
main()


I expect the output to be like this




[ 'Santa Tracker: Making a penguin-proof password','Google Duo: Stay in touch after the Holidays' ]








node.js promise async-await






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 28 '18 at 20:13







Minh Doan

















asked Dec 28 '18 at 19:48









Minh DoanMinh Doan

207




207













  • You are returning jsons before you receive any response for your API calls. The data is pushed to jsons, but the result has already been returned.

    – Sachin Gupta
    Dec 28 '18 at 20:02











  • @SachinGupta i've just edited the code. I tried using promise but resolve didnt work too.

    – Minh Doan
    Dec 28 '18 at 20:14



















  • You are returning jsons before you receive any response for your API calls. The data is pushed to jsons, but the result has already been returned.

    – Sachin Gupta
    Dec 28 '18 at 20:02











  • @SachinGupta i've just edited the code. I tried using promise but resolve didnt work too.

    – Minh Doan
    Dec 28 '18 at 20:14

















You are returning jsons before you receive any response for your API calls. The data is pushed to jsons, but the result has already been returned.

– Sachin Gupta
Dec 28 '18 at 20:02





You are returning jsons before you receive any response for your API calls. The data is pushed to jsons, but the result has already been returned.

– Sachin Gupta
Dec 28 '18 at 20:02













@SachinGupta i've just edited the code. I tried using promise but resolve didnt work too.

– Minh Doan
Dec 28 '18 at 20:14





@SachinGupta i've just edited the code. I tried using promise but resolve didnt work too.

– Minh Doan
Dec 28 '18 at 20:14












2 Answers
2






active

oldest

votes


















3














You need a separate promise for each URL request, and then use Promise.all, which will await them all and will gather the responses in an array:



function get_title() {
return Promise.all(urls.map(url => {
return new Promise(function(resolve, reject) {
browser.request(url, res => {
let body = ''
res.on('data', data => {
body += data
})
res.on('end', () => {
var json = JSON.parse(body).items[0].snippet.title
resolve(json)
})
}).end()
})
})
}





share|improve this answer































    1














    Since Promise.all() takes in an array, it helped to consume the map that you have setup. This way you also don't have to track the array:



    function get_title() {
    return Promise.all(
    urls.map(url => new Promise(function(resolve, reject) {
    browser.request(url, res => {
    let body = ''
    res.on('data', data => {
    body += data
    })
    res.on('end', () => {
    var json = JSON.parse(body).items[0].snippet.title
    resolve(json)
    })
    }).end()
    }))
    )
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53963631%2fcannot-push-item-to-array-with-map-and-async-await%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      3














      You need a separate promise for each URL request, and then use Promise.all, which will await them all and will gather the responses in an array:



      function get_title() {
      return Promise.all(urls.map(url => {
      return new Promise(function(resolve, reject) {
      browser.request(url, res => {
      let body = ''
      res.on('data', data => {
      body += data
      })
      res.on('end', () => {
      var json = JSON.parse(body).items[0].snippet.title
      resolve(json)
      })
      }).end()
      })
      })
      }





      share|improve this answer




























        3














        You need a separate promise for each URL request, and then use Promise.all, which will await them all and will gather the responses in an array:



        function get_title() {
        return Promise.all(urls.map(url => {
        return new Promise(function(resolve, reject) {
        browser.request(url, res => {
        let body = ''
        res.on('data', data => {
        body += data
        })
        res.on('end', () => {
        var json = JSON.parse(body).items[0].snippet.title
        resolve(json)
        })
        }).end()
        })
        })
        }





        share|improve this answer


























          3












          3








          3







          You need a separate promise for each URL request, and then use Promise.all, which will await them all and will gather the responses in an array:



          function get_title() {
          return Promise.all(urls.map(url => {
          return new Promise(function(resolve, reject) {
          browser.request(url, res => {
          let body = ''
          res.on('data', data => {
          body += data
          })
          res.on('end', () => {
          var json = JSON.parse(body).items[0].snippet.title
          resolve(json)
          })
          }).end()
          })
          })
          }





          share|improve this answer













          You need a separate promise for each URL request, and then use Promise.all, which will await them all and will gather the responses in an array:



          function get_title() {
          return Promise.all(urls.map(url => {
          return new Promise(function(resolve, reject) {
          browser.request(url, res => {
          let body = ''
          res.on('data', data => {
          body += data
          })
          res.on('end', () => {
          var json = JSON.parse(body).items[0].snippet.title
          resolve(json)
          })
          }).end()
          })
          })
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 28 '18 at 20:18









          trincottrincot

          120k1483115




          120k1483115

























              1














              Since Promise.all() takes in an array, it helped to consume the map that you have setup. This way you also don't have to track the array:



              function get_title() {
              return Promise.all(
              urls.map(url => new Promise(function(resolve, reject) {
              browser.request(url, res => {
              let body = ''
              res.on('data', data => {
              body += data
              })
              res.on('end', () => {
              var json = JSON.parse(body).items[0].snippet.title
              resolve(json)
              })
              }).end()
              }))
              )
              }





              share|improve this answer




























                1














                Since Promise.all() takes in an array, it helped to consume the map that you have setup. This way you also don't have to track the array:



                function get_title() {
                return Promise.all(
                urls.map(url => new Promise(function(resolve, reject) {
                browser.request(url, res => {
                let body = ''
                res.on('data', data => {
                body += data
                })
                res.on('end', () => {
                var json = JSON.parse(body).items[0].snippet.title
                resolve(json)
                })
                }).end()
                }))
                )
                }





                share|improve this answer


























                  1












                  1








                  1







                  Since Promise.all() takes in an array, it helped to consume the map that you have setup. This way you also don't have to track the array:



                  function get_title() {
                  return Promise.all(
                  urls.map(url => new Promise(function(resolve, reject) {
                  browser.request(url, res => {
                  let body = ''
                  res.on('data', data => {
                  body += data
                  })
                  res.on('end', () => {
                  var json = JSON.parse(body).items[0].snippet.title
                  resolve(json)
                  })
                  }).end()
                  }))
                  )
                  }





                  share|improve this answer













                  Since Promise.all() takes in an array, it helped to consume the map that you have setup. This way you also don't have to track the array:



                  function get_title() {
                  return Promise.all(
                  urls.map(url => new Promise(function(resolve, reject) {
                  browser.request(url, res => {
                  let body = ''
                  res.on('data', data => {
                  body += data
                  })
                  res.on('end', () => {
                  var json = JSON.parse(body).items[0].snippet.title
                  resolve(json)
                  })
                  }).end()
                  }))
                  )
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 28 '18 at 20:32









                  r0hitsharmar0hitsharma

                  971714




                  971714






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53963631%2fcannot-push-item-to-array-with-map-and-async-await%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas

                      Can't read property showImagePicker of undefined in react native iOS