1

I am trying to make a GET Request to an API and want to store the data it returns in another variable but Javascript doesn't wait for the request to be complete and log my variable as Undefined

app.get("/", function (req, res) {
    const url = "https://animechan.vercel.app/api/random";
    let str = "";
    let quote;
    
    https.get(url,(resposne)=>{
        resposne.on("data",(data)=>{
            str+=data;
        });
        resposne.on("end",()=>{
            const info=JSON.parse(str);
            quote=info.quote;
        });
    });

    console.log(quote);
    res.render("header", {
        quote: quote
    });
});

I would be glad if someone can tell me how to solve this problem and where can I study about it more as I am a beginner to javascript.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Reyno Dec 21 '22 at 12:49

2 Answers2

1

Quick answer is that you need to put that code inside of response.on('end') callback.

resposne.on("end",()=>{
   const info=JSON.parse(str);
   quote=info.quote;
   // now we can use res.render
   console.log(quote);
   res.render("header", {
      quote: quote
   });
});

However, following such approach will lead to a callback hell, unreadable and unextendable code of your project. Ideally, you should start using promises. Promises are an essential part of javascript and are a must have knowledge for a developer.

Also, I'd like to note that you don't need to implement http calls functionality from scratch or try to wrap such code into promise. Instead, it is better to use fetch api (if you are using node version 18 or above) or use corresponding libraries, for example, node-fetch.

Artem Arkhipov
  • 7,025
  • 5
  • 30
  • 52
0

All you have to do here is call res.send after the HTTP call is complete

app.get("/", function (req, res) {
    const url = "https://animechan.vercel.app/api/random";
    let str = "";
    let quote;
    
    https.get(url,(resposne)=>{
        resposne.on("data",(data)=>{
            str+=data;
        });
        resposne.on("end",()=>{
            const info=JSON.parse(str);
            quote=info.quote;

            // Send response _after_ the http call is complete
            console.log(quote);
            res.render("header", {
                quote: quote
            });
        });
    });
});

I would suggest using node's fetch, since the default HTTP client is a bit less ergonomic

Fetch API reference: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Node.js API reference: https://nodejs.org/dist/latest-v18.x/docs/api/globals.html#fetch

Shadab
  • 1,297
  • 6
  • 9