Returned array from function - TypeError: callback is not a function - javascript

I am writing a simple js function to return an array of strings fetched using the fetch API. Whenever I try to run code, I get this error: TypeError: callback is not a function
This is my code
function getFlavors(franchise, callback) {
const fetch = require('node-fetch');
let flavors= [];
fetch('url', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({ "franchise": franchise })
})
.then(res => res.json())
.then(json => {
json.forEach(element => {
flavors.push(element.flavor)
});
// console.log(flavors);
callback(flavors); <-- VALUES DISPLAYED ON CONSOLE
})
.catch(error => {
console.log(error);
})
}
let benJerrysFlavors = [];
getFlavors("ben&jerrys",benJerrysFlavors);
I am able to see the values on the console but when attempting to return the array from function, I get the callback error
Any ideas as to what might be the issue?

It should be called with a callback function passing the data to it. And you can uptate your array then with the returned data:
let benJerrysFlavors = [];
getFlavors("ben&jerrys", (ret) => {
benJerrysFlavors = ret;
});

Try to change from:
callback(flavors)
To:
callback.push(...flavors)

Related

How do I handle an API response with useState to update a state?

I am working on an API response. My aim is to take this API response to update a specified state.
Here the neccessary code snippet from my functional componenet:
const [recordImagesPayload, setRecordImagesPayload] = useState([]);
useEffect(() => {
const headers = { 'Content-Type': 'application/json' };
// const payload = JSON.stringify({ ...createPayload(), recordImage: newImage });
request(`${url}`, { headers, method: 'GET' })
.then((response: any) => response.json())
.then(json => {
var obj = JSON.parse(json);
var res: any = [];
for (var i in obj) {
res.push(obj[i]);
}
setRecordImagesPayload(res);
console.log(res);
});
}, []);
My console.is not showing the res from my last line of code. I am probably doing something wrong with the response but I don't know what to do.
Please help.
Thanks in advance. :)
I assume the request function is using fetch function, in that case you are already parsing the json response using response.json() call, so the resolved value in the next then is not json, so you don't have to use JSON.parse there
Try running this. Here instead of creating a new array and for loop, we can just use Object.values
useEffect(() => {
const headers = { 'Content-Type': 'application/json' };
// const payload = JSON.stringify({ ...createPayload(), recordImage: newImage });
request(`${url}`, { headers, method: 'GET' })
.then((response: any) => response.json())
.then(result => {
const res = Object.values(result);
setRecordImagesPayload(res);
console.log(res);
});
}, []);
Thanks #Akhil. I had a minor issue in my code regarding Typescript which was leading to the issue. The type of the result wasn't specified, but beside that, Akhil's answer was very accurate. Many thanks for the quick response and support.
Here is the final code which worked for me:
useEffect(() => {
const headers = { 'Content-Type': 'application/json' };
// const payload = JSON.stringify({ ...createPayload(), recordImage: newImage });
request(`${url}`, { headers, method: 'GET' })
.then((response: any) => response.json())
.then(result: any => {
const res = Object.values(result);
setRecordImagesPayload(res);
console.log(res);
});
}, []);

How to access value from fetch call in a variable in react

How to assign value in a variable in the Fetch call of react.
As I have made 2 API call one after another using map in JS
Was Facing the issue of how we can access data from another function
var data = ""
fetch(url,{})
.then((res)=> res.json())
.then((output) => data = output)
const numberOfProject = (project_id,callback) => {
var numprj;
fetch(accountUrl,{
method:"POST",
headers: {
'Accept':'application/json',
'Content-Type':'application/json'
},
body:JSON.stringify({"project_id": project_id})
})
.then((res) => res.json())
.then((data) => numprj = data)
.then(() => callback(numprj))
}
Now Call the function with call back
numberOfProject(item.project_id, getData)
Now in getData, we will receive the data
const getData = (response) => {
projNum = response
console.log(">>>>>>>>>>>>>>>2",projNum)
}

How to pass an argument to a function in my backend using .fetch()? ReactJS + Node

So I want to pass an integer argument to a function in my backend and have it return the data. I've been looking through the documentation and it seems like there might not be a way for me to pass an argument via the code I currently have. I just want second opinions before I consider using a different approach.
Frontend:
//is there a way for me to pass num to req in the backend?
newMarker = (num) => {
fetch('/api/getMarkers')
.then(res => res.json())
.then(mark => this.setState({ markers: mark }))
}
Backend:
//function where argument needs to be passed to, used in the request below
const fillNewMarker = async function fillNewMarker(num){
let temp;
let data;
await populartimes(markers[num].placeID)
.then(out => {data = out; temp = 'Currently ' + data.now.currently + ' full.'})
.catch(() => {temp = 'There is currently no data available.'});
markers[num].busy = temp;
}
//request
//i need num to be passed to req here
app.get('/api/newMarker', async (req,res) => {
await fillNewMarker(req);
console.log('Retrieve Data For New Marker Complete')
var mark = markers;
res.json(mark);
console.log('Sent Markers');
console.log(markers);
})
I've been working for quite a while so my brain is a little bit fried, there might be a really obvious solution that I have missed - if so, I apologize for my ignorance. Help is appreciated! TIA :)
Fix Attemp #1:
//Front end
newMarker = (num) => {
fetch('/api/newMarker', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(num) // body data type must match "Content-Type"
header
})
.then(res => res.json())
.then(mark => this.setState({ markers: mark }))
}
//method call via button
onButtonClick(){
this.newMarker(6)
//6 for testing
}
//backend
app.get('/api/newMarker', async (req,res) => {
console.log('Request received')
await fillNewMarker(req.body.num);
console.log('Retrieve Data For New Marker Complete')
var mark = markers;
res.json(mark);
console.log('Sent Markers');
console.log(markers);
})
You can pass an argument to fetch in the form of an object like
const response = await fetch('/api/getMarkers', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(num) // body data type must match "Content-Type" header
});
mark = await response.json();
this.setState({ markers: mark })
On backend receive the argument as req.body.arg_name
,In your case it would be req.body.num

Axios and response data set split to multiple arrays

I'm trying to get data from an API using axios command like
function fetchData(apiURL){
let data = [];
let options = {
method: "GET",
url: apiURL,
headers: {
"Access-Control-Allow-Origin": "*"
},
credentials: "include"
};
axios(options)
.then(response => {
data = response.data;
console.log(data);
})
.catch(function (error) {
console.log("System error : " + error);
});
return data;
}
but that will produce sets of arrays which will store arrays of JSONs from response.data in count of 100 per array set.
I haven't had problem using fetch() to retrieve all data. How I can get similar response of one large array of JSON objects instead of a split?
PS.
I have triggered that function in the
componentDidMount() {
const apiURL = process.env.REACT_APP_API;
let tableData = fetchData(apiURL);
console.log("DATA " + JSON.stringify(tableData));
this.setState({tblData : tableData});
}
Axios requests are asynchronous and return promises, so you need to adjust your example a bit so that your function returns a promise.
/**
* #return {Promise<T>}
*/
function fetchData(apiURL){
const options = {
method: "GET",
url: apiURL,
headers: {
"Access-Control-Allow-Origin": "*"
},
credentials: "include"
};
return axios(options)
.then(response => {
return response.data;
})
}
Now, when you consume this API do so asynchronously.
function somethingThatUpdatesThatUI() {
fetchData("/api/foo/bar")
.then((data) => {
//perform updates to UI or state here
})
.catch((err) => {
//alert the users that an error has happened here
})
}
You can update the componentDidMount function:
componentDidMount() {
const apiURL = process.env.REACT_APP_API;
fetchData(apiURL).then(data => {
console.log(data ${JSON.stringify(tableData)})
this.setState({tblData : data});
})
}

return undefined fetch inside AsyncStorage

I have a react-native app where I do a call to an api where it should return the JSON but I'm just having undefined.
export function fetchFromAPI() {
AsyncStorage.getItem('#token', (errToken, token) => {
let token = null;
const requestBody = { token: token };
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestBody)
})
.then((response) => response.json())
.then((responseJSON) => {
console.log(responseJSON); // <-- this shows the correct JSON data
return responseJSON;
}).catch((error) => {
// console.error(error);
});
});
}
I also call that funcion like this:
const apiData = fetchFromAPI();
If I do console.log() inside the fetch function, it returns the JSON data but if I do to apiData, it just gets undefined.
Does anyone has some idea why its like this, I'm doing something wrong?
You can use Promise to get response from fetchFromAPI function, like
export function fetchFromAPI() {
return new Promise((resolve, reject) => {
AsyncStorage.getItem('#token', (errToken, token) => {
let token = null;
const requestBody = {
token: token
};
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestBody)
})
.then((response) => response.json())
.then((responseJSON) => {
console.log(responseJSON); // <-- this shows the correct JSON data
resolve(responseJSON);
}).catch((error) => {
reject(error);
});
});
});
}
When calling the fetchFromAPI, use await, like
const apiData = await fetchFromAPI();
You can also use .then to capture the response and store it in the state, like
fetchFromAPI.then((data) => {
// use data here
});
Hope this will help!
First, you need to return the Promise created by getItem:
export function fetchFromAPI() {
return AsyncStorage.getItem('#token', (errToken, token) => {
let token = null;
const requestBody = { token: token };
return fetch(url, {
method: 'POST',
body: JSON.stringify(requestBody)
})
.then((response) => response.json())
.then((responseJSON) => {
console.log(responseJSON); // <-- this shows the correct JSON data
return Promise.resolve(responseJSON); // <-- this wraps the JSON into a Promise
}).catch((error) => {
// console.error(error);
});
});
}
Then you need to call the function like this:
fetchFromAPI().then(apiData => {...

Categories

Resources