Unable to await Axios call multiple times - javascript

Can someone explain to me why I am unable to perform consecutive axios API calls this way? I figured that since each call was awaited, then both calls would simply be treated the same way.
When I run this code, I get the following error:
TypeError: parsedEmp is not iterable at Object.listEmployees
I do not receive the same error for the Axios call above it. Here's my code:
async function listEmployees() {
const { data } = await axios.get('https://gist.githubusercontent.com/graffixnyc/febcdd2ca91ddc685c163158ee126b4f/raw/c9494f59261f655a24019d3b94dab4db9346da6e/work.json')
const parsedData = data
emp_data = []
for(comp of parsedData) {
emp_data.push([comp['company_name'],comp['employees']])
}
const { data2 } = await axios.get('https://gist.githubusercontent.com/graffixnyc/31e9ef8b7d7caa742f56dc5f5649a57f/raw/43356c676c2cdc81f81ca77b2b7f7c5105b53d7f/people.json')
const parsedEmp = data2
rosters = []
for(entry of parsedEmp) {
if(entry['id'] == e) {
company.employees.push({ first_name: entry['first_name'], last_name: entry['last_name']})
}
}
return rosters
}

Using destructuring assignment requires you to use the property names present in the source object, otherwise the resulting variables will be undefined. The Axios response object does not have a data2 property.
You would need something like this to access the data property
const response2 = await axios.get('https://...')
const parsedEmp = response2.data
or you can use this format to name the assigned variable
const { data: data2 } = await axios.get(...)
const parsedEmp = data2
or even this to save an extra line each time
const { data: parsedData } = await axios.get(/* first URL */)
// ...
const { data: parsedEmp } = await axios.get(/* second URL */)

You can have the code like below
async function listEmployees() {
const { data: parsedData } = await axios.get('https://gist.githubusercontent.com/graffixnyc/febcdd2ca91ddc685c163158ee126b4f/raw/c9494f59261f655a24019d3b94dab4db9346da6e/work.json');
const { data: parsedEmp } = await axios.get('https://gist.githubusercontent.com/graffixnyc/31e9ef8b7d7caa742f56dc5f5649a57f/raw/43356c676c2cdc81f81ca77b2b7f7c5105b53d7f/people.json');
// get the employee details
let emp_data = [];
_.map(parsedData, (data) => {
emp_data.push(data.company_name, data.employees);
});
// get the roster data
let rosters = [];
_.map(parsedEmp, (data) => {
roster.push({ first_name: data['first_name'], last_name: data['last_name']});
});
return rosters;
}

Related

VueJS get request every 20 minutes

I fetch data from a get request to display coin name information. I want this to update every 20 minutes.
For test-drive, I keep it 500 milliseconds. It always and always fetch data and add current list, so I am getting Duplicate keys detected: 'BUSDRON'. This may cause an update error this error and also my app is freezing.
How can I getting data from above link request every 20 minute, without dublicating values?
Also it
My fetch codes is here
methods: {
async fetchApi() {
const response = await fetch(
'https://api2.binance.com/api/v3/ticker/24hr'
);
const data = await response.json();
await data.forEach(element => {
this.chartData.symbols = [...this.chartData.symbols, element.symbol];
this.chartData.price = [...this.chartData.price, +element.lastPrice];
});
},
}
data: () => ({
timer: '',
)}
async created() {
this.loaded = false;
try {
this.timer = setInterval(this.fetchApi, 500);
this.loaded = true;
} catch (e) {
console.error(e);
}
},
Use uniqBy from lodash to remove duplicates.
Not sure the uniqueness would be based on the latest data. For safety, we reverse the array. After filtering the unique date, we reverse the array again in the order it should be.
methods: {
async fetchApi() {
const response = await fetch(
'https://api2.binance.com/api/v3/ticker/24hr'
);
const data = await response.json();
this.chartData = _.uniqBy([...this.data, data].reverse(), 'symbols').reverse()
}
}
Before your forEach loop, reset the arrays for symbols and price to an empty array, then push the new values to them inside of the forEach loop.
const response = await fetch(
'https://api2.binance.com/api/v3/ticker/24hr'
);
const data = await response.json();
const symbols = [];
const price = [];
data.forEach(element => {
symbols.push(element.symbol);
price.push(element.lastPrice);
});
this.chartData.symbols = symbols;
this.chartData.price = price;

Promise { <pending> } - for last async function

I have two main functions. The first one gets the SOAP data from an API. The second one parses it to json and then formats it into the object I need to store. I have been logging and seeing the return values, and as of so far until now, it's been fine. However, I am calling exports.createReturnLabelfrom my test file and all I can see is Promise { <pending> } . I am returning a value at the last function. Does this code look weird to your? How can I clean it up?
const soapRequest = require('easy-soap-request');
const xmlParser = require('xml2json')
exports.createReturnLabel = async () => {
const xml = hidden
const url = 'https://ws.paketomat.at/service-1.0.4.php';
const sampleHeaders = {
'Content-Type': 'text/xml;charset=UTF-8',
};
const auth = async () => {
const {
response
} = await soapRequest({
url: url,
headers: sampleHeaders,
xml: xml,
timeout: 2000
});
const {
body,
statusCode
} = response;
return body
}
const fetchLabel = async () => {
const soapData = await auth();
try {
const json = xmlParser.toJson(soapData)
const labelData = JSON.parse(json)["SOAP-ENV:Envelope"]["SOAP-ENV:Body"]["ns1:getLabelResponse"]
return {
courier: 'dpd',
tracking_number: labelData["return"]["paknr"],
barCode: labelData["return"]["barcodecontent"],
printLabel: labelData["return"]["label"],
_ref: null
}
} catch (e) {
return (e)
}
}
return fetchLabel()
}
calling from my test file return console.log(file.createReturnLabel())
There's an async function call inside your code.
Should be: return await fetchLabel(), so that it awaits for completion before going on its merry way.

Nothing executes after forEach loop in redux

My redux code looks like following
const getCategories = (res) => (dispatch,getState) => {
let categories = []
const result = res.results
console.log("here")
result.forEach((rawMaterial,index)=>{
if(!_.includes(categories,rawMaterial.category[0].name)){
categories.push(rawMaterial.category[0].name)
dispatch({type:UPDATE_CATEGORIES,categories})
}
});
console.log("here2")
}
Basically it is a function which pushes data into categories array from input parameter "res". What my problem is, "getCategories" function does not executes anything after forEach loop.
The below piece of chunk does not get executed in the above code.
console.log("here2")
Function executes nothing after forEach loop.
Full code
export const getRawMaterials = (params = {}) => (
dispatch,
getState,
{ fetch }
) => {
dispatch({ type: GET_RAW_MATERIALS_REQUEST, params });
const { token } = dispatch(getToken());
const { search, ordering } = getState().rawMaterials;
return fetch(
`/pands/raw-materials/?${qs.stringify({
search,
ordering
})}`,
{
method: "GET",
token,
success: res => {
const rawMaterials = res.results
dispatch({ type: GET_RAW_MATERIALS_SUCCESS, res });
const categories = getCategories(rawMaterials);
dispatch({type:UPDATE_CATEGORIES,categories})
},
failure: err => dispatch({ type: GET_RAW_MATERIALS_FAILURE })
}
);
};
//doubt here, function get return after forEach
const getCategories = (res) => {
let categories = []
const result = res;
return result.map(rawMaterial => {
if(_.includes(categories,rawMaterial.category[0].name)) return null;
return rawMaterial.category[0].name;
}
)
}
My code is not working from the following line:
const categories = getCategories(rawMaterials);
Neither it is giving an error. I think problem is with response coming from backend.
"res" is coming from backend. my data is in "res.results". When I type check "res.results" , it shows object but when I print it, it shows array of objects.

"Exit promise" with multiples fetch requests

I need to merge data from API. I do a first call to an endpoint that gives me a list of ids, then I do a request for each id. My goal is to return a list with the responses of all requests but I lost myself in promises ...
My code runs on NodeJS. Here is the code :
const fetch = require('node-fetch')
const main = (req, res) => {
fetch('ENDPOINT_THAT_GIVES_LIST_OF_IDS')
.then(response => response.json())
.then(response => {
parseIds(response)
.then(data => {
console.log(data)
res.json(data)
// I want data contains the list of responses
})
})
.catch(error => console.error(error))
}
const getAdditionalInformations = async function(id) {
let response = await fetch('CUSTOM_URL&q='+id, {
method: 'GET',
});
response = await response.json();
return response
}
const parseIds = (async raw_ids=> {
let ids= []
raw_ids.forEach(function(raw_id) {
let informations = {
// Object with data from the first request
}
let additionalInformations = await
getAdditionalInformations(raw_id['id'])
let merged = {...informations, ...additionalInformations}
ids.push(merged)
})
return ids
})
main()
I get this error : "await is only valid in async function" for this line :
let additionalInformations = await getAdditionalInformations(raw_id['id'])
Help me with promise and async/await please.
You're almost there, just a slight bit of error here with your parentheses:
// notice the parentheses'
const parseIds = async (raw_ids) => {
let ids= []
raw_ids.forEach(function(raw_id) {
let informations = {
// Object with data from the first request
}
let additionalInformations = await getAdditionalInformations(raw_id['id'])
let merged = {...informations, ...additionalInformations}
ids.push(merged)
})
return ids
}
You are missing an async after forEach
const parseIds = (async raw_ids=> {
let ids= []
raw_ids.forEach(async function(raw_id) {
let informations = {
// Object with data from the first request
}
let additionalInformations = await
getAdditionalInformations(raw_id['id'])
let merged = {...informations, ...additionalInformations}
ids.push(merged)
})
return ids
})
One suggestion: you are mixing promises (.then()) with async/await. Prefer async/await is more readable.
Note that getAdditionalInformations inside forEach doesn't wait for it to be done before going to the next entry of the array.
You can use plain old for(var i=0; .... instead

Value arriving late? “Value below was evaluated just now”

let currComp = this;
let projects = []
let dataArr = []
async function getData() {
let getProject =
await axios.get('url', {
auth: {
username: 'username',
password: 'pw'
}
})
let projects = await getProject.data.value;
let arr = []
let KPIs = []
projects.map(project => {
let item = () => axios.get(`url`, {
auth: {
username: 'username',
password: 'pw'
}
})
arr.push(item)
console.log('arr', arr)
})
let results = await axios.all(arr)
results.map(result => {
result().then(function(v) {
KPIs.push(v.data.value)
})
})
}
getData();
What I am trying to do is:
get an axios call to fetch the name of the projects.
Use those fetched names to call multiple axios calls. This is supposed to give me some data from that project.
results = await axios.all(arr) contains functions that gives me the responses to the API call.
The responses gets pushed in the the array KPIs.
When I try to console.log('KPIs', KPIs) at the end, it gives me
which seems to be an empty array, but when I open it,
it actually has the value that I want.
The problem is, when I try to use this array in my code, it only gives me the first item of the array.
I tried to search this issue online, and it only told me that the value is arriving late.
I want to use the full array with the full result.
How can I fix it?
results = await axios.all(arr) contains functions that gives me the responses to the API call.
Yes, but that's pointless. You don't want functions that return promises for responses, and there's no use to call axios.all on array of functions or await that.
You will instead need to build an array of promises, and all() and await that.
You shouldn't need to use then either. You can simplify your code a lot:
async function getData() {
const getProject = await axios.get('url', {
auth: {
username: 'username',
password: 'pw'
}
});
const projects = getProject.data.value;
const promises = projects.map(project =>
axios.get(`url`, {
auth: {
username: 'username',
password: 'pw'
}
})
);
const results = await axios.all(promises)
const KPIs = results.map(v => v.data.value);
}

Categories