Can't extract Data with For Loop (JavaScript / Fetch) - javascript

Why can't I extract the fields that I want from the for loop?
Console Log
JSON Data
document.addEventListener('DOMContentLoaded', function() {
let user = 'example';
fetch(`/jsonresponse/${user}`)
.then(response => response.json())
.then(data => {
// The line below works and prints the username
console.log(data['UsersInfo'][0].username)
// Doesn't work in a for Loop
for (let i = 0; i < data.length; i++) {
console.log(data['UsersInfo'][i].username);
}
});
Any hints would be appreciated

Your issue is in for loop you need to loop over data["UsersInfo"] not just data
vvvvvvvvvvvv
for (let i = 0; i < data["UsersInfo"].length; i++) {
console.log(data["UsersInfo"][i].username);
}
it's better to store user users in array and loop over them with for..of
const users = data["UsersInfo"];
for (const user of users) {
console.log(user.username);
}

Related

Json Array empty [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 5 months ago.
passed Json to array and console show empty but with objects inside.
but when printing with index console.log show undefind..
whats wrong ?
let pokeName = [];
let pokeId = [];
let pokeImg = [];
let pokeType = [];
let pokeMove = [];
for (let i=1; i< 21; i++) {
fetch(`https://pokeapi.co/api/v2/pokemon/${i}/`)
.then(Response => Response.json())
.then(data => {
pokeId.push(data['id']);
pokeName.push(data['name']);
const dataTypes = data['types'];
pokeType.push(dataTypes[0]['type']['name']);
const dataMoves = data['moves'];
pokeMove.push(dataMoves[0]['move']['name']);
pokeImg.push(data['sprites']['front_default']);
});
}
console.log(pokeName);
console.log(pokeId);
console.log(pokeImg);
console.log(pokeMove);
console.log(pokeType);
As I mentioned in my comment, your console.log() code runs before the fetch has returned its promise, and thus no data has been set yet.
for loops actually do not work with the await keyword and so typically you just need to convert your for loop to a for await...of loop instead. Then you can call an async function that loops through all the values you need and once all promises in the loop have been returned, the following code will execute (within the scope of the same function. Any code outside of the function will run asynchronously).
let pokeName = [];
let pokeId = [];
let pokeImg = [];
let pokeType = [];
let pokeMove = [];
let pokeCount = [];
for(let i = 1; i < 21; i++) pokeCount = [...pokeCount, i];
const _FetchPokes = async () => {
for await (const poke of pokeCount) {
await fetch(`https://pokeapi.co/api/v2/pokemon/${poke}/`)
.then(Response => Response.json())
.then(data => {
pokeId.push(data['id']);
pokeName.push(data['name']);
pokeType.push(data['types'][0]['type']['name']);
pokeMove.push(data['moves'][0]['move']['name']);
pokeImg.push(data['sprites']['front_default']);
});
}
// This will run AFTER the data has been fetched
_RunAfterFetch();
}
const _RunAfterFetch = () {
// Add any code you want to run here
// This will run AFTER the pokemon data has been fetched
console.log(pokeName[1-1]);
}
_FetchPokes();
Your console logs are running before your fetch calls are finishing. You can use async/await to solve the issue.
Something like this should work:
let pokeName = [];
let pokeId = [];
let pokeImg = [];
let pokeType = [];
let pokeMove = [];
(async function () {
for (let i = 1; i < 21; i++) {
const data = await fetch(`https://pokeapi.co/api/v2/pokemon/${i}/`);
const json = data.json();
pokeId.push(json['id']);
pokeName.push(json['name']);
const dataTypes = json['types'];
pokeType.push(dataTypes[0]['type']['name']);
const dataMoves = json['moves'];
pokeMove.push(dataMoves[0]['move']['name']);
pokeImg.push(json['sprites']['front_default']);
}
})();
console.log(pokeName);
console.log(pokeId);
console.log(pokeImg);
console.log(pokeMove);
console.log(pokeType);
here is the alternate way to fetch data
const getPokemon =async(id)=>{
return await (await fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)).json();
}
const getSerializedData = async () =>{
for (let i=1; i< 10; i++) {
const data = await getPokemon(i);
console.log(data)
}
}
getSerializedData();

For loop is not storing the data correctly, where am I making the mistake?

In the code below I am looping over results.data.data.length and I am getting the correct data and storing it correctly as well.
The data:
param1 = [6, 27, 34, 22, 23, 25, 28, 24, 26, 30, 29] // => array length 11
Now the part that I am having an issue with, in the second loop I am getting the correct output for EnrolledNum and I am getting 11 numbers outputted but individually. So far so good.
Here is the issue, when I try to store the values into the empty array var EnrolledNum = [] it's only storing the last number. I am console.log inside and outside the loop to make sure things are ok. The one inside the loop is logging it individually correctly but the outside the loop is showing me an array of length = 1 which is the last number. What is the issue here?
fetchInitialData = async () => {
this.setGlobal({ loading: true });
const ep = `${process.env.REACT_APP_API}/partners/programs/list`;
const results = await axios.get(ep);
console.log("results data", results);
var param1 = [];
for (let i = 0; i < results.data.data.length; i++) {
param1.push(results.data.data[i].id);
}
console.log("Param....", param1);
for (let j = 0; j < param1.length; j++) {
console.log('chekcingJ',j,'CheckingParam#', param1[j])
const customers_ep = `${process.env.REACT_APP_API}/partners/programs/customers/${param1[j]}`;
const customers = await axios.get(customers_ep);
console.log("customers....", customers);
var EnrolledNum = [];
EnrolledNum.push(
customers.data.data.filter(
e =>
e.status_stage === "Accepted_Paid" ||
e.status_stage === "Accepted_Manual"
).length
);
console.log("In the Loop: EnrolledNumber...", EnrolledNum);
}
console.log("Outside the Loop: EnrolledNumber...", EnrolledNum);
};
You have to move the var EnrolledNum = []; outside of the forloop
Otherwise, you are re creating the variable each time it enters in the loop, and creates it as an empty array.
Try this out:
etchInitialData = async () => {
this.setGlobal({ loading: true });
const ep = `${process.env.REACT_APP_API}/partners/programs/list`;
const results = await axios.get(ep);
console.log("results data", results);
var param1 = [];
for (let i = 0; i < results.data.data.length; i++) {
param1.push(results.data.data[i].id);
}
console.log("Param....", param1);
var EnrolledNum = [];
for (let j = 0; j < param1.length; j++) {
console.log('chekcingJ',j,'CheckingParam#', param1[j])
const customers_ep = `${process.env.REACT_APP_API}/partners/programs/customers/${param1[j]}`;
const customers = await axios.get(customers_ep);
console.log("customers....", customers);
EnrolledNum.push(
customers.data.data.filter(
e =>
e.status_stage === "Accepted_Paid" ||
e.status_stage === "Accepted_Manual"
).length
);
console.log("In the Loop: EnrolledNumber...", EnrolledNum);
}
console.log("Outside the Loop: EnrolledNumber...", EnrolledNum);
};

Javascript array returned with elements but when logging length I get zero

Trying to get values from an API using async functions. I need to be able to access the values in the array immediately.
componentDidMount() {
var devices = this.props.navigation.state.params.userInfoState.deviceIds
async function call_vstat(device, token) {
try {
let response = await fetch(
'http://app.yatis.io/api/admin/getDeviceStatus?api_access_token=' + token + '&deviceId=' + device,
);
let responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
}
var results = []
for (i = 0; i < devices.length; i++) {
var result = call_vstat(devices[i], my_token)
.then( (result) => (results.push(result) ) )
}
console.log(results.length)
console.log(results)
}
Here's the issue when I look at the logger, I get an array of length twenty one but when logging the length itself it shows zero.
If you are using async await you don't have to use the then(). What you can do is
for (i = 0; i < devices.length; i++) {
var result = await call_vstat(devices[i], my_token)
results.push(result)
}
Hope this works
As mentioned in my comments,
var promiseArray = [];
for (i = 0; i < devices.length; i++) {
promiseArray.push(call_vstat(devices[i], my_token));
}
var results = await Promise.all(promiseArray);
if (results.length > 0) {
//perform your business logic after this check to avoid any errors
}

how to set a state within a promise inside a for loop [duplicate]

This question already has answers here:
Waiting for promise in for loop
(2 answers)
Closed 4 years ago.
I have a state this.state = { PathBased : [] , ...ect}
and a function containing a for loop ,after looping this.state.data I want to add every returned element of the for loop to PathBased state ,
I can't find how to do it , could you please help
by the way
console.log(this.state.data) output is 5
async readFromLocal (){
let dirs = RNFetchBlob.fs.dirs;
let path = [];
let leng = this.state.data.length;
if(leng > 0)
{
for( var j = 0 ; j < leng; j++)
{
path[j] = dirs.PictureDir+"/folder/"+this.state.data[j].title;
const xhr = RNFetchBlob.fs.readFile(path[j], 'base64')
.then ((data) => {this.setState({PathBased:[...PathBased,data]})})
.catch ((e) => {e.message});
}
}
console.log(this.state.PathBased.length) // output = 0
}
You could make use of Promise.all and set the final result in the PathBased state. Also since setState is async you need to check the updated state in setState callback.
async readFromLocal (){
let dirs = RNFetchBlob.fs.dirs;
let path = [];
let promises = [];
let leng = this.state.data.length;
if(leng > 0) {
for( let j = 0 ; j < leng; j++) {
path[j] = dirs.PictureDir+"/folder/"+this.state.data[j].title;
promises.push(RNFetchBlob.fs.readFile(path[j], 'base64'))
}
}
Promise.all(promises)
.then(data => this.setState({PathBased: data}, () => {console.log(this.state.PathBased)})
)
.catch(e => {console.log(e.message)});
}

Order of execution in loop

I'm using this function to get some infos from google analytics and trying to stick them in a JS object in order to send it to the user.
My problem is: the console.log(obj) gets executed before the obj.push(tempObj);. So when I try to send the obj, I find it empty.
I tried to use async.each() & async.waterfall() but still had the same problem.
function getJsonFileByUser2() {
authClient.authorize((err, tokens) => {
let dimensions, webproperties;
let accounts = getAccountsByUser();
let obj = [];
for (var i = 0; i < accounts.length; i++) {
let tempObj = {
account_id: accounts[i]["id"],
account_name: accounts[i]["name"],
webproperties: []
};
webproperties = getWebPropertyIdByAccount(accounts[i]["id"]);
for (let j = 0; j < webproperties.length; j++) {
dimensions = getDimensions(accounts[i]["id"], webproperties[j]["id"]);
tempObj.webproperties.push({
id: webproperties[j]["id"],
name: webproperties[j]["name"],
dimensions: dimensions
});
}
obj.push(tempObj);
}
console.log(obj);
});
}

Categories