Reputation: 387
I have the following code
const request = require('request');
var url = "https://api.warframe.market/v1/items";
var options = {
json: true
};
var item_urls;
request(url, options, (error, res, body) => {
if (error) {
return console.log(error)
};
if (!error && res.statusCode == 200) {
item_urls = body.payload.items;
console.log("done");
};
});
It retrieves a JSON file, parses it then saves it into the items_urls
. It works fine with no problem. Note: I am running this code directly in the node REPL terminal via my IDE so that I can debug it. After the above executes I then type item_urls
at the terminal and it outputs the results. In case you are wondering why I've done it with way, this variable is to be used later in another function beyond the scope of this post. I am doing it this way because it's the only way I can save the output from "request" to a variable (explained next).
There are two issues I have:
One is that I want to encapsulate it all into a function and can't get it working. I want it as a function as I need to call this code from another function later on. Here is how I changed it:
const request = require('request');
var url = "https://api.warframe.market/v1/items";
var options = {
json: true
};
var item_urls;
function test() {
request(url, options, (error, res, body) => {
if (error) {
return console.log(error)
};
if (!error && res.statusCode == 200) {
item_urls = body.payload.items;
console.log("done");
};
});
}
As you can see, I only wrapped the "request" part of the code in a function called test. When I call this function test()
it does the same as above and outputs the data to item_urls
. The problem I have is it that I want the function to return the data, not output it to that variable. When I run test()
in the REPL it says undefined
. This is expected because the function doesn't return anything. For example I'd like to store the output in x when I run var x = test()
but again when viewing x it says undefined. I think the issue is in relation to callbacks which I haven't fully grasped yet.
The second issue is that I want the items_url
inside the function as I was told it is best practice to do so.
Here is my final code where I attempt to return the data:
const request = require('request');
var url = "https://api.warframe.market/v1/items";
var options = {
json: true
};
function test() {
var item_urls;
request(url, options, (error, res, body) => {
if (error) {
return console.log(error)
};
if (!error && res.statusCode == 200) {
item_urls = body.payload.items;
console.log("done");
};
});
return item_urls;
}
I move the items_url var declaration inside the function then use return items_url
to return it. If I then run x = test()
again it still says undefined. I have tried moving the return statement to different code blocks but it never works. What am I doing wrong? I need it to return the data.
Upvotes: 0
Views: 70
Reputation: 8125
There are many ways to solve this. Better understand the async programing.
const request = require("request");
var url = "https://api.warframe.market/v1/items";
var options = {
json: true,
};
function test() {
var item_urls;
request(url, options, (error, res, body) => {
if (error) {
return console.log(error);
}
if (!error && res.statusCode == 200) {
item_urls = body.payload.items;
console.log("done");
}
});
// return item_urls; // WIll return, before even getting data
}
// SOL 1
// USING CALLBACK
function test(cb) {
request(url, options, (error, res, body) => {
if (!error && res.statusCode == 200) {
cb(body.payload.items);
}
});
}
test((urls) => {
console.log(urls);
});
// SOL 2
// USING PROMISE
function test() {
return new Promise((r, rr) => {
request(url, options, (error, res, body) => {
if (error) {
return rr(error);
}
if (!error && res.statusCode == 200) {
return r(body.payload.items);
}
});
});
}
test().then((urls) => {
console.log(urls);
});
const {promisify} = require("util")
const pr = promisify(request)
// SOL 3
// USING ASYNC- AWAIT
async function test() {
const res = await pr(url, options)
return res.body.payload.items
}
test().then((urls) => {
console.log(urls);
});
Upvotes: 1