Object key 'undefined' [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Object key 'undefined' [duplicate]



This question already has an answer here:



I'm getting an object coming from an API and I'm creating new objects inside it with other API responses, ex:



API Response 1: Obj: a: 1, b: 2


Obj: a: 1, b: 2



API Response 2: 3


3



Creating an object: Obj.c = 3


Obj.c = 3



Final result: Obj: a: 1, b: 2, c: 3


a: 1, b: 2, c: 3


console.log(Obj) return Obj: a: 1, b: 2, c: 3

console.log(Obj.c) return undefined



I am not getting when trying to give a console.log after the .map in the properties, I can not access the created properties, returns undefined. However, when I give a console.log on any object, the created properties are there.


console.log


.map


undefined


console.log


async getGeneralInfo(token, seed)
try
API_HEADER.headers.Authorization = token;
let responseAvaliableCoins = await axios.get(
BASE_URL + "/coin",
API_HEADER
);

let avaliableCoins = responseAvaliableCoins.data.data.coins;

avaliableCoins.map(async (coin, index) =>
if (coin.status === "active")
let responseCreateAddress = await axios.post(
BASE_URL + "/coin/" + coin.abbreviation + "/address",
seed ,
API_HEADER
);

avaliableCoins[index].address =
responseCreateAddress.data.data.address;

let responseBalance = await axios.get(
BASE_URL +
"/coin/" +
coin.abbreviation +
"/balance/" +
coin.address,
API_HEADER
);

avaliableCoins.token = responseBalance.headers[HEADER_RESPONSE];
avaliableCoins[index].balance = responseBalance.data.data;
else
avaliableCoins[index].address = undefined;
avaliableCoins[index].balance = undefined;

);

console.warn(avaliableCoins[0].balance); //undefined
console.warn(avaliableCoins[0]["balance"]); //undefined
console.warn(avaliableCoins[0].address); //undefined
console.warn(avaliableCoins[0]["address"]); //undefined

console.warn("avaliableCoins", avaliableCoins); //All objects are here
console.warn("avaliableCoins[0]", avaliableCoins[0]); //All objects are here

return avaliableCoins;
catch (error)
internalServerError();
return;




update -----
enter image description here



This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





Did you check to ensure that the 0 index has something. I might just dump the entire availableCoins array to see what you're working with. console.log(avaliableCoins)
– bob
Aug 12 at 2:27





My theory is that you're using Google Chrome, which shows a "live" view when you log objects. Your code isn't awaiting the result of all the promises returned from the .map.
– 4castle
Aug 12 at 2:32


await


.map





const coinUpdates = availableCoins.map( ... etc ... ); await Promise.all(coinUpdates);
– 4castle
Aug 12 at 2:41


const coinUpdates = availableCoins.map( ... etc ... ); await Promise.all(coinUpdates);





That i next to the object says it was evaluated just now. So possibly its not the same value at the time you wrote to the console.
– Nimeshka Srimal
Aug 12 at 2:45


i




1 Answer
1



The function used in map is asynchronous.


map



Right now map is being called on all of the coins and before all the asynchronous data can come back the code has already moved on to the console.warn() calls.


map


console.warn()



availableCoins will eventually be updated with all the asynchronous data as it is returned, but there is a race condition here since the code is not explicitly waiting for that to happen.


availableCoins



Here is the recommended approach:


async


map


Promise


async


Promise.all()


Promises



Here is a simplified version that demonostrates the approach:


const getData = () =>
return Promise.resolve('data');


export const getGeneralInfo = async () =>
let avaliableCoins = [
a: 1 ,
a: 2
]

const promises = avaliableCoins.map(async (coin) =>
let response = await getData();
// modify coin and return it
coin.data = response;
return coin;
);

const updatedCoins = await Promise.all(promises);

console.log(updatedCoins); // [a: 1, data: 'data', a: 2, data: 'data']

return updatedCoins;



Your modified function would look like this:


async getGeneralInfo(token, seed)
try
API_HEADER.headers.Authorization = token;
let responseAvaliableCoins = await axios.get(
BASE_URL + "/coin",
API_HEADER
);

let avaliableCoins = responseAvaliableCoins.data.data.coins;

const promises = avaliableCoins.map(async (coin) =>
if (coin.status === "active")
let responseCreateAddress = await axios.post(
BASE_URL + "/coin/" + coin.abbreviation + "/address",
seed ,
API_HEADER
);

coin.address =
responseCreateAddress.data.data.address;

let responseBalance = await axios.get(
BASE_URL +
"/coin/" +
coin.abbreviation +
"/balance/" +
coin.address,
API_HEADER
);

coin.token = responseBalance.headers[HEADER_RESPONSE];
coin.balance = responseBalance.data.data;
else
coin.address = undefined;
coin.balance = undefined;

return coin;
);

availableCoins = await Promise.all(promises);

console.warn(avaliableCoins[0].balance); //undefined
console.warn(avaliableCoins[0]["balance"]); //undefined
console.warn(avaliableCoins[0].address); //undefined
console.warn(avaliableCoins[0]["address"]); //undefined

console.warn("avaliableCoins", avaliableCoins); //All objects are here
console.warn("avaliableCoins[0]", avaliableCoins[0]); //All objects are here

return avaliableCoins;
catch (error)
internalServerError();
return;


Popular posts from this blog

make 2 or more post in bootsrap

Store custom data using WC_Cart add_to_cart() method in Woocommerce 3

Firebase Auth - with Email and Password - Check user already registered