Unexpected end of JSON input error from DELETE method fetch - javascript

Here is the network screenshot
I am constantly getting the "Unexpected end of JSON input" error in console when I run this code, but it works (the item is deleted when I refresh page, but it doesn't rerender on it's own even tho the state is chenged and throws this error when I run it)
I checked if the problem is the type of id that I send when I call the function, and there is nothing wrong with it
const deleteScreen = (id:any) =>{
console.log(id)
fetch(`http://localhost:5002/admin/example?exampleId=${id}`, {
method: 'DELETE',
headers: {
'Content-type': 'application/json',
'Authorization' : `Bearer ${token.token}`
},
})
.then((response) => response.json())
.then((data) => {
console.log(data.result)
setAllScreens(data.result)
})
.catch((err) => {
console.log(err.message)
})
}

It's look like there is something wrong with your then block. Try with just console response instead response.json(). Or you can check with network tab response all well.

Related

REACT: Fetch returns response as not ok but Network tab shows data

I am new to react and when I am trying to fetch the json response into UI I am getting error, even though the network tab shows the json response.
Please help me in resolving this.
Code-
useEffect(() => {
console.log('Inside UseEffect');
fetch(`http://localhost:8080/api/hello`
,{ mode: 'no-cors', method: 'GET' })
.then((response) => {
if(!response.ok) throw new Error(`This is an HTTP error: The status is ${response.status}`);
else return response.json();
})
.then((json) => {
this.setState({
teamList: json});
console.log(this.state.teamList);
})
.catch(err => console.log(err));
}, [] )
Network tab response looks like-
[{"id":1,"title":"Team1"},{"id":2,"title":"Team2"},{"id":3,"title":"Team3"},{"id":4,"title":"Team4"},{"id":5,"title":"Team5"},{"id":6,"title":"Team6"}]
And the Console tab has below output-
Inside UseEffect
Error: This is an HTTP error: The status is 0
Instead of
if(!response.ok) throw new Error(`This is an HTTP error: The status is ${response.status}`);
else return response.json();
in the then anonymous function do console.log({response})
You can then see in the console what the object looks like and interrupt how to extract the data from it.
response.ok is most likely undefined

React/Javascript - TypeError: Cannot read properties of undefined (reading 'json')

React & Javascript noob here, I'm trying to build my first React project. What I want to do is to have a button that fetches automatically the last matches I played on a game. I'm using a API that, when called correctly, returns this json:
{data:
[{id: 0, internal_id: "_map_id_halo1_pillar_of_autumn", name: "The Pillar Of Autumn"},
…]}
I want to extract the name for each object of data and display an unordered list below the button.
But when I click the button, the browser displays the error:
TypeError: Cannot read properties of undefined (reading 'json')
The code that does what I mentioned is as follows:
async fetchHaloMaps()
{
const url = 'https://cryptum.halodotapi.com/games/hmcc/metadata/maps'
const mapNames = [];
fetch(url, {
"method": 'GET',
"headers": {
'Content-Type': 'application/json',
'Cryptum-API-Version': '2.3-alpha',
'Authorization': 'Cryptum-Token XXX'
}
})
.then(response => {
console.log(response);
if (!response.ok)
throw new Error("Response not ok!");
})
.then(response =>
response.json())
.then(data => {
const i=0;
for (const d of data)
{
mapNames[i] = d.name;
i++;
}
this.setState((state, props) => ({
numberOfMaps : i
}));
})
.catch(error => {
console.log("There was an error: " + error);
});
}
I think I'm "parsing" the JSON in the wrong way. But in the JSON, data i indeed an array with a "name" attribute. So I wanted to cycle the data array and copy the attribute "name", but the code above is not working.
I know the HTTP request with fetch does succeed, since in the console.log I can see the response object and it has the 200 OK field, and I can see the JSON associated with the browser developer tools.
You did not return anything from this .then:
.then(response => {
console.log(response);
if (!response.ok)
throw new Error("Response not ok!");
})
so there is no value that gets passed along to the next .then.
While you could do return response, a better approach would be to remove the intermediate .then entirely - only insert a .then when you need to wait for something asynchronous. At the time you get the response, you can check if it's OK and then return the .json(), without waiting in between.
.then(response => {
if (!response.ok) {
throw new Error("Response not ok!");
}
return response.json();
})
.then(data => {

How to console log the whole content of error in the catch block of a fetch call when there is a network failure

I am making a network request in a react native project using the fetch api. It works well in normal conditions but when I am offline the catch block just gives as result of the logging error but when I do err.message I get "Network request failed" I was hoping to get some codes. How can I get the possible codes to check for in anticipation of a network failure?
I tried logging the entire err and I get nothing but when I use err.message I get "Network request failed"
fetch(url, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
}
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({ procesing: false });
this.setState({ music: responseJson });
})
.catch(err => {
console.log(err)
console.log(err.message)
})
for console.log(err), I expected to have and error code and the corresponding message but I get nothing
If I understand correctly, you are expecting error for some testing purposes.
First of all, try to console.log any string, like
console.log('error');
If nothing happens (I am pretty sure it won't), try throwing error if response is not okay.
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("http://httpstat.us/500")
.then(handleErrors)
.then(function(response) {
console.log("ok");
}).catch(function(error) {
console.log(error);
});
Source: https://www.tjvantoll.com/2015/09/13/fetch-and-errors/
As per this answer, you can use a function to stringify the error:
var stringifyError = function(err, filter, space) {
var plainObject = {};
Object.getOwnPropertyNames(err).forEach(function(key) {
plainObject[key] = err[key];
});
return JSON.stringify(plainObject, filter, space);
};
stringifyError(someError, null, '\t');

Why is my JavaScript Fetch not able to get the error object

I have a JavaScript that makes a Fetch post call to the backend of the site. If the post-call goes well, the Fetch is able to handle the response. If something goes wrong in the post-call, the Fetch is not able to handle the error.
This are my codes:
async function startFetch(url, data_post){
return fetch(url, {
method: 'POST', // or 'PUT'
body: JSON.stringify(data_post), // data can be `string` or {object}!
headers:{
'Content-Type': 'application/json'
}
})
.then(response => response.json());
}
async function makeFetch(arrRows){
let url = 'somebackendpost';
for(const item of ArrRows){
let data_post = {};
data.name = item;
await startFetch(url, data_post)
.then(data => {
//when the fetch is okay, this part is executed
console.log(data);
//do other things like output to html
$('#result').append('<p>' + data.result + '</p>');
})
.catch(error ={
//a timeout 504 error occured, but this part seemed not to execute
console.log('error is', error);
//the code below is wrong (but has since been removed then)
//Is this the reason why the catch error part did not work?
//Since the code below has been removed, can I expect the catch error to now work?
$('#result').append('<p>' + data.result + '</p>');
});
}
}
function startProcess(){
//called by button click
let arrRows = ["Row1", "Row2", "Row3"];
makeFetch(arrRows);
}
At the time, the code was executed, there was a server issue. The browser console displayed a Gateway timeout error 504. Here is the console logs:
Fetch failed loading: POST "mysite/somebackendpost"
POST mysite/somebackendpost 504 (GATEWAY TIMEOUT)
error is SyntaxError: Unexpected end of JSON input
at fetch.then.response
Uncaught (in promise) ReferenceError: X is not defined
at startFetch.then.catch.error
Try updating your startFetch method to first check that the fetch response is "ok" before attempting to parse the response as json. This will catch most error scenarios (that are currently going undetected), before you attempt to parse json.
So, an update as follows should allow you to respond to errors correctly:
async function startFetch(url, data_post){
return fetch(url, {
method: 'POST', // or 'PUT'
body: JSON.stringify(data_post), // data can be `string` or {object}!
headers:{
'Content-Type': 'application/json'
}
})
.then(response => {
// Check that the response is valid and reject an error
// response to prevent subsequent attempt to parse json
if(!response.ok) {
return Promise.reject('Response not ok with status ' + response.status);
}
return response;
})
.then(response => response.json());
}
Hope this helps!

catching error body using axios post

I am sending a status code 422 from my backend code with response body which contains the description of the error. I am using axios post as below to post a request:
post: function(url, reqBody) {
const request = axios({
baseURL: config.apiUrl,
url: url,
headers: {
'Content-Type': 'application/json',
'Authorization': sessionStorage.getItem('token')
},
method: 'POST',
data: reqBody,
responseType: 'json'
});
return request
.then((res) => {
return res;
})
.catch((error) => {
console.log(error);
return error;
})
}
The problem is when backend is returning error code 422, the error object I am catching has no information about response body. Is there any way I can retrieve the error text?
I had this same issue and the answer (as per Axios >= 0.13) is to specifically check error.response.data:
axios({
...
}).then((response) => {
....
}).catch((error) => {
if( error.response ){
console.log(error.response.data); // => the response payload
}
});
See here for more details.
The "body" of an AXIOS error response depends from the type of response the request had.
If you would like full details about this issue you can see this blogpost: How to catch the body of an error in AXIOS.
In summary AXIOS will return 3 different body depending from the error:
Wrong request, we have actually done something wrong in our request (missing argument, bad format), that is has not actually been sent. When this happen, we can access the information using error.message.
axios.get('wrongSetup')
.then((response) => {})
.catch((error) => {
console.log(error.message);
})
Bad Network request: This happen when the server we are trying to reach does not respond at all. This can either be due to the server being down, or the URL being wrong.
In this case, we can access the information of the request using error.request.
axios.get('network error')
.then((response) => {})
.catch((error) => {
console.log(error.request );
});
Error status: This is the most common of the request. This can happen with any request that returns with a status that is different than 200. It can be unauthorised, not found, internal error and more. When this error happen, we are able to grasp the information of the request by accessing the parameter specified in the snippets below. For the data (as asked above) we need to access the error.response.data.
axios.get('errorStatus')
.then((response) => {})
.catch((error) => {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
})
For those using await/async and Typescript
try {
const response = await axios.post(url, body)
} catch (error) {
console.log(error.response.data);
}
For react native it just worked for me
api.METHOD('endPonit', body)
.then(response => {
//...
})
.catch (error => {
const errorMessage = JSON.parse(error.request.response)
console.log(errorMessage.message)
})
We can check error.response.data as #JoeTidee said. But in cases response payload is blob type? You can get error response body with the below code.
axios({
...
}).then((response) => {
....
}).catch(async (error) => {
const response = error.response
if(typeof response.data.text === function){
console.log(await response.data.text()); // => the response payload
} else {
console.log(response.data)
}
});
I am returning a string from backend but expecting a json as response type. So I need to return an object instead of string for axios to process it properly.
In my case I wanted to retrieve a response 404 error message (body).
I got body with error.response.data but I couldn't display it because the type was ArrayBuffer.
Solution:
axios.get(url, { responseType: 'arraybuffer' }).then(
response => {...},
error => {
const decoder = new TextDecoder()
console.log(decoder.decode(error.response.data))
}
)
Related posts:
Converting between strings and ArrayBuffers

Categories