I have looked at the following articles, which all go into depth about asynchronous calls return undefined.
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
This doesn't answer my question, however. In my example, I am using async
, and await
, and .then
. The async function IS returning something, and populating the array, however it is the format of the array, and the ability of dealing with the array that I am struggling with.
I am using the following code to populate an array with objects from my MongoDB database.
const initialClasses = [];
const getInitData = async () => {
await axios.get('http://localhost:5000/classes/api/')
.then(response => {
initialClasses.push(response.data)
})
.catch(error => {
console.log(error)
});
}
getInitData();
console.log(initialClasses);
When I console.log initialClasses, however, I get the following array:
[]
0: (3) [{…}, {…}, {…}] // objects provided from the async call
length: 1
__proto__: Array(0)
When I try to access this array, using console.log(initialClasses[0]);
i get undefined.
What have I done wrong in creating this array? Is there a better, cleaner way to do this which I have overlooked? Thanks.
First I think I'd recommend revisiting Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference as your understanding of asynchronous behavior grows. I believe it's at the root of the problem here (hence why this feels like a duplicate to some members of the community).
Why you get undefined
when you call console.log(initialClasses[0])
will depend on when you call that and again we'd expect undefined if you call it too early and misunderstand how async
works.
But instead of getting into those weeds, let's get to the root of your question: Is there a cleaner way? Yes! Probably the misunderstanding here comes from the way you've structured this. You can simplify it a lot and get the same functionality.
You can call the following inside of an async function
const response = await axios.get('http://localhost:5000/classes/api/');
let initialClasses = response.data;
This would be the preferred way since whatever you are wanting to do with the response from that endpoint is fundamentally asynchronous. This way the response data won't be 'nested' either.