Passing an Array of Objects returned from a fetch command back to the calling function (Django and JS)
I've spent days and days on this trying various techniques I have red on here and other forums but just cant get my head a round it.
I've tried .map(), I've tried global variables, I've tried everything I can think of. steep learning curve
I have split one long function into several smaller functions to make the code more readable and just more functional, the below code is called by a main function I'm using for mapping, the purpose of the code below is to go and fetch data from a model (via views.py) and then pass it back to the main function, it will be a data containing names, cities, towns, countries, it worked fine before I split the long function but now wont pass variables.
Where I console.log 'the objects the towns' it looks ok in the console but once outside of that fetch Im lost, Ive tried to return the data from within the fetch function mappointobject (which I believe is an array of objects) but it wont, Ive tried to put a 'await' on final console.log but nothing, it seems no matter what I've tried fails after the closing fetch function brackets }), the main function just says to me 'undefined'
Below is what I get at the console.log right before the fetch closing brackets
the objects the towns (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
let mappointsobject;
async function radiocontacttownslist() {
fetch(`/conlogger/getradiocontactsdata`, { //this fetch command via views.py gets the data in the radiocontacts list
method: 'POST',
credentials : 'same-origin',
headers: {//'Accept': 'application/json', //Django needs these headers
'X-CSRFToken': getCookie("csrftoken"),
'Content-type': 'application/json' , //Indicates that the request body format is JSON.
'X-Requested-With': 'XMLHttpRequest'
},
})
.then(response => response.json())
//get the promise and when data comes back, take the response and convert and return as JSON
.then(result => {
console.log(result);
mappointsobject = JSON.parse(result) //convert from JSON to javascript object - also see next line
console.log('the objects the towns',mappointsobject) // this is all the objects and all the data from the radio contacts table
}) //end of fetch brackets
console.log('townlisttestoutsideoffetch',mappointsobject)
return mappointsobject;
}
I've tried global variables, I've tried .map() (totally lost with this but gave it a crack), I've tried passing strings and numbers back and they passed back to the main function fine, It doesn't like the array or there is a timing conflict. I have also tried using 'await' at various points in the main function and this function but cant seem to rationalize it.
Looking for guidance, I'm still learning and have a lot to learn, thankyou
It looks like you want to return the value that you are fetching from the api. Right now, with the way your code is written, you are using async
with the function without await
anywhere in your body.
fetch
returns a Promise, which is an asynchronous bit of code. When a Promise is encountered, the browser does not wait for it to finish running, or resolve, and instead just continues with the rest of the code.
I am guessing that townlisttestoutsideoffetch
gets logged out before the objects the towns
does, and it's because the fetch
is being fired off and then code execution immediately continues and console logs. Then, when the promise resolves, the other console log gets run.
Here's how you can restructure your code for it to work as expected:
async function radiocontacttownslist() {
return await fetch(`/conlogger/getradiocontactsdata`, {
method: 'POST',
credentials : 'same-origin',
headers: {//'Accept': 'application/json',
'X-CSRFToken': getCookie("csrftoken"),
'Content-type': 'application/json' ,
'X-Requested-With': 'XMLHttpRequest'
},
})
.then(response => JSON.parse(response.json()))
}
let mappointsobject = radiocontacttownslist()
The main thing to notice here is that we set mappointsobject
to the result of the radiocontacttownslist
function call, which return
s a value.
Notice that the await
is before the fetch -- it will wait for the promise to resolve, and then the return
returns the value.
Thanks Alex, I had been trying to return values outside to the fetch function and had also tried 'await' at the fetch level but never thought I could actually return and await at the fetch level, I tried this as you said above and the function didn't crash but the values weren't passed back to the calling function either but I could access the data (array of objects) from the calling function in the global variable mappointsobject here is what I ended up with below -
let mappointsobject;
async function radiocontacttownslist() {
return await fetch(`/conlogger/getradiocontactsdata`, { //this fetch command via views.py gets the data in the radiocontacts list
method: 'POST',
credentials : 'same-origin',
headers: {//'Accept': 'application/json', //Django needs these headers
'X-CSRFToken': getCookie("csrftoken"),
'Content-type': 'application/json' , //Indicates that the request body format is JSON.
'X-Requested-With': 'XMLHttpRequest'
},
})
.then(response => response.json())
//get the promise and when data comes back, take the response and convert and return as JSON
.then(result => {
console.log(result);
mappointsobject = JSON.parse(result) //convert from JSON to javascript object - also see next line
//console.log('the objects the towns',mappointsobject) // this is all the objects and all the data from the radio contacts table
}) //end of fetch .then brackets
}
the calling function looks like this
const mappointsobjectreturned = await radiocontacttownslist();
console.log('rtrndfromradiocontacttownslist', mappointsobject) //trying to return object from function called above
I tried doing a console.log on mappointsobjectreturned but it just said undefined as it previously had in the console before I made the changes, not until I accessed the variable mappointsobject directly which was populate in the function that was called did the console then give me the array of objects rather then undefined.
rtrndfromradiocontacttownslist (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
So it is working but I dont like how I have done it, can you see any reason it wouldnt work with just the return and await at the fetch level in the called function? Is the console.log in the calling function still trying to use a pre returned value or have I not defined a variable correctly, thanks so much for your help.