How to change variable value in Axios response? - javascript

I'm trying to change a variable value in axios's then. Here is my example:
var pts = [];
axios.get('http://www.example.com')
.then(function (response) {
pts = response.data;
});
console.log(pts);
The pts variable just returns empty array. I just want to use it out of the GET query. How can I change it?

use the new elegant way async & await it is more neat and readable
let pts = [];
const getData = async () => {
const {data} = await axios.get("http://www.example.com");
pts = data;
return data
}
getData();
console.log(pts);

The request is asynchronous so the pts gets printed first and then the function gets called
What you can do is use a promise and make your request as follows:
const func1 = () => {
return axios.get("http://www.example.com").then(response => {return response})
}
func1().then(data => {
pts = data;
})

Related

async api call function seems to work until test

I am trying to get some exchange data and use it for some logic. I thought the most straight forward idea would be to use a function where I could pass the different pairs I may want, there are many per exchange. If I console log inside the function when the data ends everything works find. When i try and get the response when it is ready I get undefined, please see the commented console log and my last line.
I understand that I am missing something with async and the way it works.
const https = require('https');
async function binancePairPrice (binancePair) {
let url = 'https://api.binance.com/api/v3/ticker/bookTicker';
let queryString = '?symbol='
https.get(url+queryString+binancePair,(res) => {
console.log(res.statusCode);
let binanceBookTicker = '';
let binanceBookTickerJson =
res.on('data', data => {
binanceBookTicker += data;
});
res.on('end', () => {
binanceBookTickerJson = JSON.parse(binanceBookTicker);
//console.log(binanceBookTickerJson);
return (binanceBookTickerJson)
});
});
};
binancePairPrice('BTCUSDT').then(console.log);
day one javascript coming from python. This is quite a step from what I am used to writing. Any docs or links would be appreciated too.
thansk
https.get doesn't return something that can be promisified, so you can't await it.
You can do something else which is wrapping the https.get call within a Promise and then await it when calling binancePairPrice.
const https = require('https')
async function binancePairPrice (binancePair) {
let url = 'https://api.binance.com/api/v3/ticker/bookTicker';
let queryString = '?symbol='
return new Promise((resolve) => {
https.get(url, res => {
let binanceBookTicker = '';
let binanceBookTickerJson =
res.on('data', data => {
binanceBookTicker += data;
});
res.on('end', () => {
resolve() = >
{
binanceBookTickerJson = JSON.parse(binanceBookTicker);
return (binanceBookTickerJson)
}
});
})
})
}
(async () => await binancePairPrice('BTCUSDT))()
Your binancePairPrice function doesn't wait for the end callback to happen and therefore just carries on and returns undefined.
You need to return a Promise and then resolve the promise with the value you want to return from the function.
Promise basics
Using the Promise() constructor
async function binancePairPrice (binancePair) {
return new Promise((resolve, reject) => {
let url = 'https://api.binance.com/api/v3/ticker/bookTicker';
let queryString = '?symbol=';
https.get(url+queryString+binancePair,(res) => {
console.log(res.statusCode);
let binanceBookTicker = '';
let binanceBookTickerJson =
res.on('data', data => {
binanceBookTicker += data;
});
res.on('end', () => {
binanceBookTickerJson = JSON.parse(binanceBookTicker);
//console.log(binanceBookTickerJson);
resolve(binanceBookTickerJson)
});
});
});
}

Array pushes data fetched from an api twice

I'm making a call to an api and I'm using async/await. I'm pushing the response data to a global array, but for some reason it is pushing it twice. I'm making two fetch requests, receiving the response, pushing it to an array, and then console logging the data array. How can I prevent it from pushing the data to the array twice?
var data = [];
const getData = async () => {
const f1_data = await fetch(url + countryOne.value)
.then(response => response.json())
.then((result) => {
var index = result.length - 1;
var confirmed = result[index].Confirmed;
textOne.textContent = result[index].CountryCode + " TOTAL CASES : " + confirmed;
data.push(confirmed);
console.log(data);
})
const f2_data = await fetch(url + countryTwo.value)
.then(response => response.json())
.then((result) => {
var index = result.length - 1;
var confirmed = result[index].Confirmed;
textTwo.textContent = result[index].CountryCode + " TOTAL CASES : " + confirmed;
data.push(confirmed);
console.log(data);
})
};
getData();
Expected output
Example: 56789, 89768
Output
56789, 56789, 89768, 89768
As other suggested, since you are using aysnc and await, might as well get rid of the .then() flow.
It seems like your getData() has been called multiple times, it is unsafe to keep data array outside of your getData function block. You might want to do something like this: (takes few seconds to get the api data..)
const getData = async () => {
const url = 'https://api.covid19api.com/country/'
const query = '?from=2020-12-31T00:00:00Z&to=2021-01-01T00:00:00Z';
let data = [];
const f1_data = await fetch(`${url}singapore${query}`);
const f1_json = await f1_data.json();
data.push(f1_json[0].Confirmed);
const f2_data = await fetch(`${url}malaysia${query}`);
const f2_json = await f2_data.json();
data.push(f2_json[0].Confirmed);
return data;
};
const logData = async () => {
let data = await getData();
console.log(data);
}
logData();
return the data from your async getData function.

loadData() returning empty array

I'm trying to return an array of objects to a function, and looking at the debugger, it looks like it just returns an empty array.
Here's the function that I'm hoping to use:
// load from json file
loadData(filepath) {
let rooms = [];
fetch(filepath)
.then(
res => res.json()
)
.then(function (data) {
// console.log(data);
for (let i = 0; i < data.rooms.length; i++) {
rooms.push(data.rooms[i]);
}
});
return rooms;
}
I go into the debugger, and I see the rooms from data.rooms getting pushed to my local rooms object, but when I get back up to my init() function that's supposed to use this rooms data:
let rooms = this.loadData(this.datapath); // TODO: make games load from json data
for (let i = 0; i < rooms.length; i++) {
this.addRoom(rooms[i].name, rooms[i].getText, rooms[i].prompts, rooms[i].requirements);
}
It looks like it's passed an empty array. Is there a scoping issue or something I'm missing? I'm not very experienced with fetch/promises/JSON.
Happy to provide any further info that may be useful. Thanks!
The problem is that your local variable rooms will be returned before the async fetch finish.
You can just simple await the fetch statements and make the function async:
async loadData(filepath) {
let rooms = [];
const response = await fetch(filepath);
const data = await response.json();
console.log(data);
for (let i = 0; i < data.rooms.length; i++) {
rooms.push(data.rooms[i]);
}
return rooms;
}
let rooms = await this.loadData(this.datapath);
Try this, if it did not work let me know.
// load from json file
async function call() {
const loadData = async filepath => {
let rooms = [];
return await fetch(filepath)
.then(res => res.json())
.then(async data => {
rooms = await [...data];
return rooms;
});
};
let x = await loadData("https://jsonplaceholder.typicode.com/posts");
console.log("TEST: ", x);
}
call();

Why I always get a Promise form my return value?

Below is my function
async function test() {
const data= [];
for (let i = 0; i <= 5; i = i + 1) {
const payload: any = await postExampleApi(i);
data.push(payload);
}
return data;
}
export const getData = test().then((data) => {
console.log(data);
return data;
});
I try to call api six times with different params(number 0 - 5) each times.
I can have my data array from console.log, however, when I import this getData function from another file, I always get a Promise{...} not data array.
Did I do something wrong?
Whenever you do this :
let x = promise().then(cb)
You get "x" as promise only. All you should do is when requiring this file, do a "dot then" to get the data.
So wherever you require the file, do this :
let test = require('./test');
test.then((dataArray) => console.log(data));
Because you are calling a async function getData === async test(), if you don't want to deal with the then, you can make your call like await getData()

Use asynchronous function inside _.map()

I am using lodash library for iteration. I have used _.map() function for this purpose. I have a problem that I have an asynchronous function inside _.map(). My code is like this:
let dataToRender = {};
let modifiedData = _.map(myArray, (element) => {
dataToRender.uuid = element.UID;
dataToRender.pendingAmountReceived = element.$.SR;
dataToRender.orderID = element.TransactionID;
dataToRender.orderAmount = element.TransactionValue;
dataToRender.orderDate = moment(element.TransactionTime, 'YYYY-MM-DDTHH:mm:ss');
dataToRender.goal = element.Product.replace('amp;', '&');
dataToRender.currentStatus = 'waiting';
//Here CheckFilter is my asynchrounous function
//I have to do calculation base on the response of this checkFilter
checkFilter(requireParams)
.then(data => {
//If the response returned from checkFilter is false I have to include this data
if (!data) {
return requireParams;
}
});
});
res.json(modifiedData);
But I am getting just null in modifiedData. How to get all the data?
Bluebird provides a number of promise helper methods including Promise.map() which will only resolve when all returned promises are resolved.
The only problem is you will end up with undefined values in your results for when the checkFilter function is truthey. lodash's _.compact function can help here or you can use _.filter if you have more specific filtering needs.
const Promise = require('bluebird');
let dataToRender = {};
Promise.map(myArray, element => {
dataToRender.uuid = element.UID;
dataToRender.pendingAmountReceived = element.$.SR;
dataToRender.orderID = element.TransactionID;
dataToRender.orderAmount = element.TransactionValue;
dataToRender.orderDate = moment(element.TransactionTime, 'YYYY-MM-DDTHH:mm:ss');
dataToRender.goal = element.Product.replace('amp;', '&');
dataToRender.currentStatus = 'waiting';
return checkFilter(requireParams)
.then(data => {
// If the response returned from checkFilter is false I have to include this data
if (!data) return requireParams;
});
})
.then(results => res.json(_.compact(results)) );

Categories