How can I log wrong responses in a fetch statement?
My code looks something like this:
eturn fetch('myurl.com', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then((response) => response.json())
.then((responseData) => {
console.log(responseData); // This logs nothing
}).catch((error) => {
console.log("Error " + error); // This logs something
});
The log from my code example is Error SyntaxError: JSON Parse error: Unrecognized token '<'. I think this is because of XDebug sending some error messages, but I have absolutly no Idea what might have gone wrong. It looks like the Response starts with '<', so I think it is a html tag.
Is it possible to show this response? That would be very useful to find my mistake.
try this and be sure that url return correct json format:
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
loading: false,
data: res.data
}, () => {
console.log("log something")
});
})
.catch(error => {
console.log(error);
this.setState({ loading:false, error });
});
Related
I don't know if it is a bug or something wrong with my code. But the first fetch takes to long to respond.
Although this problem is only on the app. When I run it on the web, it works like a charm and load within 2 to 3 seconds. While on the app it takes more than a minute.
fetch(url)
.then((response)=>response.json() )
.then((responseJson)=>{
setDATA(responseJson);
setLoading(false);
})
.catch((err)=>{
console.log(err)
})
I also used Axios but having the same problem
axios.get(url)
.then(res => {
setDATA(res.data);
setLoading(false)
console.log(DATA);
})
If you think this can be a large data problem. the SQL db has only 2 field to fetch from.
And It is same when i try to login user. Same slow fetch and slow response
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password
}),
})
.then(response => response.json())
.then((responseJson) => {
setLoading(false);
// If server response message same as Data Matched
if (responseJson === 'Data Matched') {
// save user to async
// AsyncStorage.setItem('isLoggedIn', true);
//send user to main page
navigation.navigate('flatlist');
} else {
alert(responseJson);
console.log(responseJson)
}
})
.catch((error) => {
setLoading(false);
console.log(error);
});
};
It also seems like a bug as I read this
Newbie to React Native. I am trying to use FormData to upload image and data using the fetch API following example from Spencer Carli. My back end works fine, when I use postman the image uploads to the database storage without any problem. But when I try to upload image via the mobile device I get
upload error [SyntaxError: JSON Parse error: Unexpected identifier "Tunnel"]
Below is my code
const createFormData = (photo, body) => {
const data = new FormData();
data.append('file', {
name: photo.fileName,
type: photo.type,
uri:
Platform.OS === 'android' ? photo.uri : photo.uri.replace('file://', ''),
});
Object.keys(body).forEach(key => {
data.append(key, body[key]);
});
return data;
};
const uploadPhotoHandler = async (photo) => {
const token = await AsyncStorage.getItem('token');
fetch('http://ba9737b7.ngrok.io/post', {
headers: {'Authorization': 'Bearer ' + token},
method: 'POST',
body: createFormData(photo, {
title: 'Golden twisted knots',
postType: 'hair',
duration: 45}),
})
.then(response => response.json())
.then(response => {
console.log('upload succes', response);
alert('Upload success!');
})
.catch(error => {
console.log('upload error', error);
alert('Upload failed!');
});
};
I think the problem is from this line
.then(response => response.json())
but I don't know why.
The problem is because you are not getting a JSON response. When you are trying to parse to JSON.
You can solve it checking first the response status code, try this.
const uploadPhotoHandler = async (photo) => {
const token = await AsyncStorage.getItem('token');
fetch('http://ba9737b7.ngrok.io/post', {
headers: {'Authorization': 'Bearer ' + token},
method: 'POST',
body: createFormData(photo, {
title: 'Golden twisted knots',
postType: 'hair',
duration: 45}),
})
.then(response => {
//If the response status code is between 200-299, if so
if(response.ok) return response.json();
//if not, throw a error
throw new Error('Network response was not ok');
})
.then(response => {
console.log('upload succes', response);
alert('Upload success!');
})
.catch(error => {
console.log('upload error', error);
alert('Upload failed!');
});
};
I'm fairly new to react native and I'm trying to test out using the FacePlusPlus API (https://console.faceplusplus.com/documents/5679127).
Here, I've tried putting 'api_key' in the body, however, I've also tried putting it in headers too. Neither has worked.
componentDidMount() {
var url = 'https://api-us.faceplusplus.com/facepp/v3/detect';
return fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
api_key: 'blahblahblah',
api_secret: 'blahblahblah',
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
data: responseJson,
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});
}
In render(), I put console.log(this.state.data) where data is an array to see the response, however all I keep getting is
Object {
"error_message": "MISSING_ARGUMENTS: api_key",
}
To solve this problem you have to set Content-Type header to 'application/x-www-form-urlencoded'
and pass your arguments as formData.
I put the example with using 'request' npm package.
const request = require('request');
request.post({url:'https://api-us.faceplusplus.com/facepp/v3/compare', formData: {
api_key: 'your api key',
api_secret: 'your api secret',
image_url1: 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/George_Lucas_cropped_2009.jpg/220px-George_Lucas_cropped_2009.jpg',
image_url2: 'https://imgix.bustle.com/uploads/getty/2018/6/13/e4c5921d-3e23-4f13-87fe-0180005d0ace-getty-929360234.jpg?w=970&h=582&fit=crop&crop=faces&auto=format&q=70'
}}, (err, httpResponse, body) => {
if (err) {
return console.error('error', err);
}
console.log('success ', JSON.parse(body));
});
I'm having issues when using FETCH.
I am trying to make a POST request using FETCH in react-native.
fetch("http://www.example.co.uk/login", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'test',
password: 'test123',
})
})
.then((response) => response.json())
.then((responseData) => {
console.log(
"POST Response",
"Response Body -> " + JSON.stringify(responseData)
)
})
.done();
}
When I inspect this call using Charles it is recorded as a GET request and the username and password that should be in the body are not there.
Can anyone help with this issue?
I had this issue when the POST request was to an HTTPS (rather than HTTP) server. For some reason, it would somewhere along the way be converted into a GET request.
It turns out what I was doing incorrectly was sending the request to http://myserver.com:80 rather than to https://myserver.com:443. Once I switched it over to the proper prefix and ports, the request would properly send as a POST.
This worked for me:
let data = {
method: 'POST',
credentials: 'same-origin',
mode: 'same-origin',
body: JSON.stringify({
appoid: appo_id
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': cookie.load('csrftoken')
}
}
return fetch('/appointments/get_appos', data)
.then(response => response.json()) // promise
.then(json => dispatch(receiveAppos(json)))
}
Use FormData. Problem is with JSON.stringify. You can directly import, its not third party
import FormData from 'FormData';
...
var data = new FormData();
data.append("username", "ABCD");
data.append("password", "1234");
fetch('YOUR_URL', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
body:data,
})
.then((response) => response.json())
.then((responseJson) => {
console.log('response object:',responseJson)
})
.catch((error) => {
console.error(error);
});
I had the same kind of issue. You have to assign the object, not sure why.
let options = {};
options.body = formdata;
options.header = header;
options.method = 'post';
In my case, the redirect was caused by wrongly formed url for the POST request:
http://localhost:90/Worx/drupal/d8/www//jsonapi
double slash before jsonapi
Because of the wrong url, the browser was redirecting the request and changing the method from POST to GET.
I was able to debug it after reading this:
https://serverfault.com/questions/434205/nginx-https-rewrite-turns-post-to-get
If you wanna do POST request using fetch, You can do like that
fetch('url?email=a#gmail.com&password=a#gmail.com', {
method: 'POST'
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
// this.setState({
// data: responseJson
// })
})
.catch((error) => {
console.error(error);
});
Redirection of url converts the POST request into GET requests.(Don't know why)
So make sure of adding trailing arrows if any.
like :"http://www.example.co.uk/login/"
I had the same issue. In my case I had an extra / at the end of my route. I removed it and problem solved.
http://google.com/someData/ to http://google.com/someData
I have made some changes and tested it, works fine for me, check below all the changes:
constructor(props) {
super(props);
this.state = { isLoading: true};
this.getRemoteData();
}
getRemoteData = () => {
fetch('http://www.example.co.uk/login', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'test',
password: 'test123',
})
})
.then((response) => response.json())
.then((responseData) => {
console.log("RESULTS HERE:", responseData)
this.setState({
isLoading: false,
dataSource: responseJson,
}, function(){
});
})
.catch((error) =>{
console.error(error);
})
};
Check your OPTIONS response. It probably has a 302 redirect or similar.
In our case, Django didn't like it if the URL didn't end in a /
Similar to Rishijay's answer, my issue was with JSON.stringify not properly converting the body of POST request.
The way I solved this was using build from the search-params node module to make it work.
My fetch contents had body like this body: build({...})
This worked for me!
const params = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
id: '1',
name: 'user',
age: '26',
}),
};
fetch('https://yourapi/', params)
.then(response => response.json())
.then(data => console.log(data));
When using fetch:
fetch(REQUEST_URL, {
method: 'get',
dataType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then((response) =>
{
response.json() // << This is the problem
})
.then((responseData) => { // responseData = undefined
console.log(responseData);
});
}).catch(function(err) {
console.log(err);
})
.done();
The following works works, do you know why? :
JSON.parse(response._bodyText)
The chaining response should look more like this, specifically the response.json part. Then you should get an Object back in console.log.
.then(response => response.json())
.then(response => {
console.log(response)
}
Fetch is a little hard to get your head around. I am new to this so dont shoot me down if flames here but response data is another promise and you need to return response data and then handle that promise with yet another then statement where you can finally log the response, also your are missing some return statements in your promises:
var makeRequest = function(){
fetch('https://jsonplaceholder.typicode.com/posts/1', {
method: 'get',
dataType: 'jsonp',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then((response) => {
return response.json() // << This is the problem
})
.then((responseData) => { // responseData = undefined
addTestToPage(responseData.title);
return responseData;
})
.catch(function(err) {
console.log(err);
})
}
function addTestToPage(textToAdd){
var para = document.createElement("p");
var node = document.createTextNode(textToAdd);
para.appendChild(node);
var element = document.getElementsByTagName("body")[0];
element.appendChild(para);
}
makeRequest();
hope that helps see: https://jsfiddle.net/byz17L4L/
Here's how it finally worked out in my case:
fetch('http://localhost:3001/questions', {
method: 'GET',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
}
})
.then(response => { return response.json();})
.then(responseData => {console.log(responseData); return responseData;})
.then(data => {this.setState({"questions" : data});})
.catch(err => {
console.log("fetch error" + err);
});
}
because you didn't return response.json() in the first then.
import React, {useEffect} from 'react';
useEffect(() => {
getRecipes();
}, []);
const getRecipes = async () => {
const response = await fetch(
`https://........`
);
const data = await response.json();
console.log(data);
Use this method You can easily fatch data.
fetch(weatherIng + zipCode +apiKey)
.then(response => response.json())
.then(response => {
console.log(response.main);
this.setState({
weather: ((response.main.temp * (9/5))-459.67).toFixed(0),
humidity:((response.main.humidity * (9/5))-459.67).toFixed(0)
})
It will think that you are trying to declare something if you don't enclose it in its own:
.then(response => {
console.log(response.main);
}) . " around the this.setState