Fetch method POST - response data is Promise pending - reactjs

I have a component which does fetch method='POST' in one of its functions:
handleSubmit(context) {
let json = {
username: this.state.username,
password: this.state.password,
}
json = JSON.stringify(json)
fetch(`/api/auth/token/`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: json,
})
.then(response => response.json())
.then(response => this.loginSuccess(context, response))
}
And this is the loginSuccess function:
loginSuccess(context, response) {
console.log('Login Success!')
context.toggleLoginModal()
context.toggleLoggedIn()
context.setUsername(response.profile_username)
context.setUserId(response.profile_id)
}
The problem with this code is, if the response doesn't lie between 200 and 300, like a Bad Request, all the code in loginSuccess will still get executed which shouldn't happen.
So, I have changed
.then(response => response.json())
.then(response => this.loginSuccess(context, response))
to:
.then(response => {
response.status >= 200 && response.status < 300 ?
this.loginSuccess(context, response.json())
:
console.log(response)
})
Now, in loginSuccess method, the argument response is Promise {<pending>} and response.profile_username is undefined.
How do the solve this?

The Promise has not been fulfilled. Try something like :
.then(response => {
response.ok ?
response.json().then(json => { this.loginSuccess(context, json) })
:
console.log(response)
})

Related

ReactJS: post request with data through fetch

In my app component, I have state features that contains an array(1500) of arrays(9). I want to send the state (or large array) to my backend so I can run my model and return labels with the following function:
const getLabels = (model) => {
fetch('/spotify/get-labels', {headers: {
'model': model,
'features': features
}})
.then(response => response.json())
.then(data => setLabels(data))
}
However, the response has status 431. This was kinda expected, but I'm not sure how to transmit the data to my backend efficiently. Maybe convert it to json and then put in the headers of my request?
You can try something like this with fetch:
fetch('/spotify/get-labels', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ model, features }),
})
.then((response) => response.json())
.then((data) => {
// Boom!
})
.catch((error) => {
// An error happened!
});
or with axios
axios
.post('/spotify/get-labels', { model, features })
.then((data) => {
// Boom!
})
.catch((error) => {
// An error happened!
});
As far as I'm understanding your concern, I guess passing the 'model': model,'features': features in body should work.
Or using Axios, you can make the request. It exactly like Axios but far better
axios({
url: '/spotify/get-labels',
method: "post",
data: {
'model': model,
'features': features
},
})
.then((response) => response.json())
.then(data => setLabels(data))
.catch((error) => {
console.log("error : ", JSON.parse(error));
});

Cannot get componentDidMount() to update empty array via this.setState with fetched JSON data

I have an empty array declared as such:
class EditPlaylistDetails extends Component {
constructor(props) {
super(props);
this.state = {
allPlaylists: []
}
};
And my ComponentDidMount() is:
componentDidMount() {
fetch('http://localhost:5040/playlist/', {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': this.props.sessionToken
})
}).then((response) => response.json())
.then((res) => {
console.log(res);
}).then((res) => {
this.setState({
allPlaylists: res
},
() => console.log(this.state.allPlaylists));
})
};
Two problems:
#1) When I try to call upon this fetched data via a .map function, it comes back as "undefined".
#2) The '() => console.log(this.state.allPlaylists))' code snippet doesn't even fire off at all. It doesn't attempt to execute the console.log.
I am able to console.log(res) within that snippet of code and it displays the updated allPlaylists array with all of the info without issue.
Add return to the second promise handler
componentDidMount() {
fetch('http://localhost:5040/playlist/', {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': this.props.sessionToken
})
}).then((response) => response.json())
.then((res) => {
console.log(res);
return res;
}).then((res) => {
this.setState({
allPlaylists: res
},
() => console.log(this.state.allPlaylists));
})
};
For one of my projects, removing the { before this.setState( worked.
componentDidMount() {
fetch('http://localhost:5040/playlist/', {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': this.props.sessionToken
})
}).then((response) => response.json())
.then((res) => {console.log(res);})
.then((res) => this.setState({allPlaylists: res})};

Unhandled Rejection (TypeError): Cannot read property 'error' of undefined

I'm fairly new to React and I've been trying to create a SignUp page, however, I'm stuck in this error. Can someone give me any indication on what I should do in order to solve this error?
Signup Method:
// = Action =
// Sign up
export const signup = user => {
return fetch(
`${API}/signup`,
{
method: 'POST',
headers: {
Accept:'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(user)
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
}
Rewrite Signup method (ps: I only changed the .catch handler)
`
// Sign up
export const signup = user => {
return fetch(
`${API}/signup`,
{
method: 'POST',
headers: {
Accept:'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(user)
})
.then(response => {
return response.json();
})
.catch(err =>
console.log(err));
return err;
}
`
You need to wrap up your fetch logic inside a Promise to return a value to the caller.
export const signup = user => {
return new Promise((resolve, reject) => {
fetch(`${API}/signup`,
{
method: 'POST',
headers: {
Accept:'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify(user)
})
.then(response => response.json())
.then(jsonData => resolve(jsonData))
.catch(err => resolve({error: `something went wrong err : ${err}`}));
})
}
signup(user).then(data => {
if (data.error) {
// handle error case
} else {
// handle success case
}
})
Now your signup method will return a value. Your data variable won't be undefined anymore.
I hope it helps, feel free to add comments or ask me more details

Api call works on postman but Doenst work on my code

So I have to update some user info ,it works fine on postman but when I try to type it in react-native I must be doing something wrong in the body of the fetch method. In postman I set x-www-form-urlencoded and type the keys like this :
Key ----- Value
moto ----- test
and that seems to work,but when I try to do the same on my code I somehow fail at it,here is my code
updateUser(){
return fetch(url,{
method: "PATCH",
headers: {
"X-Auth-Token": bearerToken,
"Content-Type":"application/x-www-form-urlencoded"
},
body: JSON.stringify({
moto: this.state.moto
}
})
}
)
I get 200 response which means the call works but I must be seting the parameter moto wrong somehow.
Any ideas ?
"Content-Type":"application/x-www-form-urlencoded"
should be
"Content-Type":"application/json"
form-urlencoded is way different from your body: JSON.stringify().
You'll want to use a FormData object instead:
const body = new FormData();
body.append('moto', this.state.moto);
fetch(url, {
method: "PATCH",
headers: {
"X-Auth-Token": bearerToken,
"Content-Type": "application/x-www-form-urlencoded"
},
body,
})
APICall = () => {
fetch(‘Your http URL’, {
method: 'PATCH',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
‘X-Auth-Token’: bearerToken,
},
body: JSON.stringify({
moto: this.state.moto
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson.statuscode == 1) {
Alert.alert('Success');
} else {
Alert.alert(responseJson.message);
}
}).catch((error) => {
console.error(error);
});
}
finally fixed it by seting body to
body:
`moto=${this.state.moto}`
it appears that urlencoded headers require parameters in the form of
parameter1=value1&parameter2=value2
componentDidMount() {
return fetch(“Your URL”, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"Authorization": “token”
},
body: "firstName=Nikhil&favColor=blue&password=easytoguess"
})
.then((response) => response.json())
.then(function (data) {
alert(“Success”)
console.log('Request succeeded with JSON response', data);
})
.catch(function (error) {
alert("error occur")
console.log('Request failed', error);
});
}
const formData = new FormData();
formData.append('email', 'test#gmail.com');
formData.append('password', '123456');
fetch("https://test.com/api/login", {
method: 'post',
body: formData
})
.then(res => res.json())
.then(
(result) => {
console.log(result);
}).catch(err => {
console.log(err);
})

React-Native : How to get callback of api call in another class

I am calling a web service
Here is my code:
var result;
export function callPostApi(urlStr, params)
{
fetch(urlStr, {method: "POST", headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(params)})
.then((response) => response.json())
.then((responseData) => {
result = JSON.stringify(responseData)
})
.catch((error) => { console.error(error);
Alert.alert('Alert Title failure' + JSON.stringify(error))
})
.done();
return result
}
I am calling from here:
callapi(){
var dict = {
email: 'at#gmail.com',
password: '123456',
}
result = callPostApi('http://demo.com', dict)
}
Currently, it is calling in Async mode that we want but code is written below this method getting execute immediately after calling of above method
i want callback when result from sever has received so that i can execute code written below the above method is execute after receiving response from server.
You need to use Promises.
Change your callPostApi function to return a Promise, then you can chain additional then, catch and finally calls.
export function callPostApi(urlStr, params) {
return fetch(urlStr, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(params)
})
.then((response) => response.json())
.then((responseData) => {
result = JSON.stringify(responseData)
})
.catch((error) => {
console.error(error);
Alert.alert('Alert Title failure' + JSON.stringify(error))
});
}
callapi() {
callPostApi('http://demo.com', {
email: 'at#gmail.com',
password: '123456',
})
.then((response) => {
// Continue your code here...
});
}

Resources