I am getting an error when i was calling an post request in use effect hook and i got the response as promise pending, but the object is there, please see the response and please provide a perfect code to map this response.
code
function Comment({ id }) {
const [data, setdata] = useState([]);
console.log(id);
useEffect(() => {
const query = `
query{
forumAnswerId(id:${id}){
forumAnswerBody
forumAnswerTime
forumAnswerCode1
forumAnswerCode2
forumAnswerCode3
forumAnswerAuthor
forumAnswerBoolean
forumAnswerCode1Title
forumAnswerCode2Title
forumAnswerCode3Title
}
forumComment(forumAnswerComment:${id}){
forumAnswerCommentPost
forumAnswerCommentBody
forumAnswerCommentAuthor
forumAnswerCommentTime
}
}
`;
const opts = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
};
const res = fetch('http://127.0.0.1:8000', opts).then((res) => res.json());
setdata(res);
}, []);
return <div></div>;
}
export default Comment;
here you are:
fetch('http://127.0.0.1:8000', opts)
.then((res) => res.json())
.then(r=> setdata(r))
promise result cannot be accessed outside. You need to set data inside the then function
Using Promise
fetch('http://127.0.0.1:8000', opts).then((res) => setdata(res.json()));
Using Async await
const res=await fetch('http://127.0.0.1:8000', opts)
setdata(res.json())
useEffect(() => {
const fetchData = async () => {
const query = `
query{
forumAnswerId(id:${id}){
forumAnswerBody
forumAnswerTime
forumAnswerCode1
forumAnswerCode2
forumAnswerCode3
forumAnswerAuthor
forumAnswerBoolean
forumAnswerCode1Title
forumAnswerCode2Title
forumAnswerCode3Title
}
forumComment(forumAnswerComment:${id}){
forumAnswerCommentPost
forumAnswerCommentBody
forumAnswerCommentAuthor
forumAnswerCommentTime
}
};`
const opts = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
};
const res = await fetch('http://127.0.0.1:8000', opts).then((res) => res.json());
setdata(res);
}
fetchData();
}, []);
Related
When posting data to an API and get a response, if I hardcode the body data inside the fetch call (body: "XYZ12345") it works fine, this is an example:
const vatValidationRequest =
fetch(
'/api/vies/validateVAT.php', {
method: 'POST',
body: "XYZ12345",
headers: {
'Content-Type': 'application/text'
}
})
.then((response) => response.text())
.then((responseText) => {
return responseText;
});
const validateVAT = async () => {
const viesResponse = await vatValidationRequest;
console.log(viesResponse);
};
validateVAT();
However, if I try to pass the body data as an argument (body: vatNumber), the validateVAT() function returns "undefined". This is what's not working:
const vatValidationRequest = (vatNumber) => {
fetch(
'/api/vies/validateVAT.php', {
method: 'POST',
body: vatNumber,
headers: {
'Content-Type': 'application/text'
}
})
.then((response) => response.text())
.then((responseText) => {
return responseText;
});
}
const validateVAT = async (vatNumber) => {
const viesResponse = await vatValidationRequest(vatNumber);
console.log(viesResponse);
};
validateVAT("XYZ12345");
Any clues about how to pass the argument to the async function? thanks!
The problem is that you are not returning the response from the method. You should do this:
const vatValidationRequest = (vatNumber) => {
return fetch(
'/api/vies/validateVAT.php', {
method: 'POST',
body: vatNumber,
headers: {
'Content-Type': 'application/text'
}
})
.then((response) => response.text())
.then((responseText) => {
return responseText;
});
}
const validateVAT = async (vatNumber) => {
const viesResponse = await vatValidationRequest(vatNumber);
console.log(viesResponse);
};
validateVAT("XYZ12345");
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);
});
}, []);
I m trying to GET response using fetch API not stuck in a error as I mentioned below. Here's my code
const DefaultLayout = () => {
let history = useHistory()
const callHomePage = async () => {
try {
const res = fetch('http://localhost:4000/api/authenticate', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
credentials: 'include',
})
console.log(res)
const data = await res.json()
console.log(data)
if (!res.status === 200) {
const error = new Error(res.error)
throw error
}
} catch (err) {
console.log(err)
history.push('login')
}
}
Error: TypeError: res.json is not a function
Promise {} shows pending
const DefaultLayout = () => {
let history = useHistory()
const callHomePage = async () => {
try {
const res = await fetch('http://localhost:4000/api/authenticate', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
credentials: 'include',
})
console.log(res)
const data = await res.json()
console.log(data)
if (!res.status === 200) {
const error = new Error(res.error)
throw error
}
} catch (err) {
console.log(err)
history.push('login')
}
}
You need to await the fetch statement and then call the .json method of the response.
const res = await fetch(...)
data = await res.json();
Read more: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I've this code into pages folder on my NextJS environment. It gets data calling an external API Rest, and it's working because the console.log(response); line show me by console the Json API response. The problem I've is that I get this error in browser:
TypeError: Cannot read property 'json' of undefined
Corresponding with this line code:
const data = await res.json();
This is the complete file with the code:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data Json: ", data);
return { props: { data } };
};
This is the Json API response that I see by console:
{
account: [
{
id: '7051321',
type: 'probe',
status: 'open',
newAccount: [Object],
lastDate: '2020-07-04',
taxExcluded: [Object],
totalRecover: [Object],
documentLinks: []
},
]
}
Any idea how can I solve it?
Thanks in advance.
UPDATE
Here the code working good:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try {
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data JSON: ", data);
return { props: { data } };
} catch (error) {
console.log("Data ERROR: ", error);
}
};
There are a couple of things you have to change.
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
return response; // 1. Add this line. You need to return the response.
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const data = await getFetch(invoicesUrl, params);
// const data = await res.json(); 2. Remove this you have already converted to JSON by calling .json in getFetch
console.log("Data Json: ", data); // Make sure this prints the data.
return { props: { data } };
};
You have return statement in wrong place.
When the function is expecting a return. You need to return when the statements are executed not inside the promise then function because it is an async callback function which is not sync with the statement inside getFetchfunction. I hope i have made things clear. Below is the code which will any how return something
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try{
const res = await getFetch(invoicesUrl, params);
console.log("Data Json: ", res);
}catch(error){
console.log("Data Json: ", error);
}
return { props: { res } };
};
I follow the example in https://scotch.io/tutorials/create-a-custom-usefetch-react-hook, to perform a fetch. All works.
I change it slightly to make a POST with 'Accept': 'application/json' and 'Content-Type': 'application/json' as per https://stackoverflow.com/a/29823632. However, no matter how I post, it is still of Text/Html context type.
const useFetch = (url, body) => {
const [response, setResponse] = React.useState(null);
const [error, setError] = React.useState(null);
React.useEffect(() => {
const FetchData = async () => {
try {
const method = "POST"
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
const options = {
method,
headers
};
if (body) options.body = JSON.stringify(body);
const res = await fetch(url, options);
const json = await res.json();
setResponse(json);
} catch (error) {
setError(error);
}
};
FetchData();
}, []);
return { response, error };
};
export default useFetch
What did I do wrong?
I'd say the answer depends on your request URL. Is your endpoint only capable of returning type text/html? What resource are you requesting?