-1

I found these answers, but couldn't figure how to implement:


There is a 'callback' function in app.post at the bottom of the code. It is supposed to return the array created in httpsYtGetFunc. It returns the array with null value. Rest of the array is empty.

app.js

// Declaring variables for the function 'httpsYtGetFunc'
let apiKey = "";
let urlOfYtGetFunc = "";
let resultOfYtGetFunc = "";
let extractedResultOfYtGetFunc = [];

// This function GETs data, parses it, pushes required values in an array.
function httpsYtGetFunc(queryOfYtGetFunc, callback) {
  
  apiKey = "AI...MI"
  urlOfYtGetFunc = "https://www.googleapis.com/youtube/v3/search?key=" + apiKey + "&part=snippet&q=" + queryOfYtGetFunc + "&maxResults=4&order=relevance&type=video";

  // GETting data and storing it in chunks.
  https.get(urlOfYtGetFunc, (response) => {
    const chunks = []
    response.on('data', (d) => {
      chunks.push(d)
    })

    // Parsing the chunks
    response.on('end', () => {
      resultOfYtGetFunc = JSON.parse((Buffer.concat(chunks).toString()))
      // console.log(resultOfYtGetFunc)

      // Extracting useful data, and allocating it.
      for (i = 0; i < (resultOfYtGetFunc.items).length; i++) {
        extractedResultOfYtGetFunc.push(resultOfYtGetFunc.items[i].id.videoId);
        // console.log(extractedResultOfYtGetFunc);
      }
    })
  })
  callback (null, extractedResultOfYtGetFunc);
}

// Client makes POST request.
app.post("/", function(req, res) {

  query = "niall";

  // The callback
  ytQueryAppJs = httpsYtGetFunc(query, (ytQueryAppJs) => {
    console.log("ytQueryAppJs:");
    console.log(ytQueryAppJs);
  });
});

The console logs only null.

I believe that callback (null, extractedResultOfYtGetFunc); is running before https.get finishes.

Could somebody please suggest how to fix it and log all the results?

Thank you so much.


This is the link to original question:

How to synchronize 'time-consuming value allotment' of a variable, with the next commands, in nodejs?

Varun
  • 73
  • 1
  • 10
  • Does this answer your question? [How to return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – jonrsharpe May 30 '21 at 07:41
  • @jonrsharpe Thank you for looking it up. I have tried the method "2. Restructure Code" of the [answer](https://stackoverflow.com/a/16825593/14597561) in the question above. I'm sharing the problem that I faced while implementing it. – Varun May 30 '21 at 07:49

2 Answers2

1

response.on('end', () associate a function to the "end" event of https.get method. When you call callback (null, extractedResultOfYtGetFunc); outside of the https.get() block, the https request has not been finish yet, and the extractedResultOfYtGetFunc array is empty.

You need to move the callback function to the response.on('end') block

function httpsYtGetFunc(queryOfYtGetFunc, callback) {
  apiKey = "AI...MI"
  urlOfYtGetFunc = "https://www.googleapis.com/youtube/v3/search?key=" + apiKey + "&part=snippet&q=" + queryOfYtGetFunc + "&maxResults=4&order=relevance&type=video";

  // GETting data and storing it in chunks.
  https.get(urlOfYtGetFunc, (response) => {
    const chunks = []
    response.on('data', (d) => {
      chunks.push(d)
    })

    // Parsing the chunks
    response.on('end', () => {
      resultOfYtGetFunc = JSON.parse((Buffer.concat(chunks).toString()))
      // console.log(resultOfYtGetFunc)

      // Extracting useful data, and allocating it.
      for (i = 0; i < (resultOfYtGetFunc.items).length; i++) {
        extractedResultOfYtGetFunc.push(resultOfYtGetFunc.items[i].id.videoId);
        // console.log(extractedResultOfYtGetFunc);
      }

      callback (null, extractedResultOfYtGetFunc); // move the callback here
    })  
  })
  // callback (null, extractedResultOfYtGetFunc);
}

EDIT

You will need to add 1 more parameter in the callback function to receive the error, if any. ytQueryAppJs = httpsYtGetFunc(query, (err, ytQueryAppJs) => {

Đăng Khoa Đinh
  • 5,038
  • 3
  • 15
  • 33
  • This seems to solve the issue. I do not know why but I'm returned with `TypeError: Cannot set property 'length' of undefined`. I checked, and the API quota limit has not exceeded. (I can't verify if this has, indeed, solved the issue.) – Varun May 30 '21 at 08:48
  • Thank you so much, pal. I had some unnecessary code 'uncommented', which was causing the issue. On a side note, could you please elaborate how do we use `response.on('error')`? – Varun May 30 '21 at 08:59
  • 1
    I read the document [here](https://nodejs.org/api/https.html#https_https_get_options_callback), the `response.on('error')` is used to handle error when you send the request and cannot receive the desired response. For example, when you received error 404. It makes the code more reliable – Đăng Khoa Đinh May 30 '21 at 09:01
  • 1
    Update: I had to remove the `null` argument to make it work. – Varun May 30 '21 at 09:02
  • Oh, alright. `.on('error', (e) => { console.error(e); });` This is what I was looking for. :) – Varun May 30 '21 at 09:05
  • Ah, I noticed that you declare only 1 parameter in the callback `ytQueryAppJs = httpsYtGetFunc(query, (ytQueryAppJs) => {` If you change to `ytQueryAppJs = httpsYtGetFunc(query, (err, ytQueryAppJs) => {` you won't need to remove the 'null' argument – Đăng Khoa Đinh May 30 '21 at 09:05
  • Yes, it did work. Could you please explain this syntax? – Varun May 30 '21 at 09:13
  • When you call the callback function, you're passing 2 parameters `callback (null, extractedResultOfYtGetFunc);`. So when you declare the function, you need 2 parameters :) – Đăng Khoa Đinh May 30 '21 at 09:15
  • Alright. What else can we put instead of `null`? I'm assuming that putting `null` won't log us the error (shall any.) – Varun May 30 '21 at 09:17
  • the `null` indicates that there is no error. When you encounter an error (in `response.on('error'))` , you need to call the callback like: `callback(error)`, then the caller knows that there is an error. – Đăng Khoa Đinh May 30 '21 at 09:19
  • Oh, okay. I'm not exactly clear with the syntax as on how to implement it. But I get the concept. Thank you so much for sparing your time and educating me. :) – Varun May 30 '21 at 09:26
-1

I'm not Node.js developer but I belive that callback (null, extractedResultOfYtGetFunc); need to be called in http.get callback function.

EDITED move to response.on('end' callback

Something like that:

function httpsYtGetFunc(queryOfYtGetFunc, callback) {
  apiKey = "AI...MI"
  urlOfYtGetFunc = "https://www.googleapis.com/youtube/v3/search?key=" + apiKey + "&part=snippet&q=" + queryOfYtGetFunc + "&maxResults=4&order=relevance&type=video";

  // GETting data and storing it in chunks.
  https.get(urlOfYtGetFunc, (response) => {
    const chunks = []
    response.on('data', (d) => {
      chunks.push(d)
    })

    // Parsing the chunks
    response.on('end', () => {
      resultOfYtGetFunc = JSON.parse((Buffer.concat(chunks).toString()))
      // console.log(resultOfYtGetFunc)

      // Extracting useful data, and allocating it.
      for (i = 0; i < (resultOfYtGetFunc.items).length; i++) {
        extractedResultOfYtGetFunc.push(resultOfYtGetFunc.items[i].id.videoId);
        // console.log(extractedResultOfYtGetFunc);
      }
      callback (null, extractedResultOfYtGetFunc);
    })
  })
}
Kazys
  • 377
  • 2
  • 12
  • Yes, I tried doing the same. But it didn't work. – Varun May 30 '21 at 07:52
  • 1
    Then try inside response.on('end'... it seems to be called at the end of respons accoriding to (https://stackoverflow.com/questions/36659002/what-does-response-on-mean-node-js) "...The two you have above are response.on('data'...) which is when you get the data and response.on('end'...) is at the end of the response, simple as that!" – Kazys May 30 '21 at 08:29