I am working on Reactjs redux on front-end and Rails api as a back-end.
So now i call api with Fetch api method but the problem is i cannot get readable error message like what i got inside the network tabs
this is my function
export function create_user(user,userInfoParams={}) { return function (dispatch) { dispatch(update_user(user)); return fetch(deafaultUrl + '/v1/users/', { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, method: "POST", body: JSON.stringify(userInfoParams) }) .then(function(response) { console.log(response); console.log(response.body); console.log(response.message); console.log(response.errors); console.log(response.json()); dispatch(update_errors(response)); if (response.status >= 400) { throw new Error("Bad response from server"); } }) .then(function(json){ console.log("succeed json re"); // We can dispatch many times! // Here, we update the app state with the results of the API call. dispatch(update_user(json)); }); } }
But when errors came i cannot figure out how to get readable response message like i got when i check on my browser network tabs
So this is what i got from the network tabs when i got errors.
My console
This is my rails code
def create user = User.new(user_params) if user.save #UserMailer.account_activation(user).deliver_now render json: user, status: 201 else render json: { errors: user.errors }, status: 422 end end
But i cannot find out how can i get that inside my function
Thanks!
To fetch a user we need: fetch('https://api.github.com/users/USERNAME') . If the response has status 200 , call . json() to read the JS object. Otherwise, if a fetch fails, or the response has non-200 status, we just return null in the resulting array.
JavaScript | fetch() Method. The fetch() method in JavaScript is used to request to the server and load the information on the webpages. The request can be of any APIs that return the data of the format JSON or XML. This method returns a promise.
json() The json() method of the Response interface takes a Response stream and reads it to completion. It returns a promise which resolves with the result of parsing the body text as JSON .
Since the text is hidden inside promise within response object, it needs to be handled like a promise to see it.
fetch(bla) .then(res => { if(!res.ok) { return res.text().then(text => { throw new Error(text) }) } else { return res.json(); } }) .catch(err => { console.log('caught it!',err); });
Similar to your answer, but with a bit more explanation... I first check if the response is ok, and then generate the error from the response.text()
only for the cases that we have a successful response. Thus, network errors (which are not ok
) would still generate their own error without being converted to text. Then those errors are caught in the downstream catch
.
Here is my solution - I pulled the core fetch function into a wrapper function:
const fetchJSON = (...args) => { return fetch(...args) .then(res => { if(res.ok) { return res.json() } return res.text().then(text => {throw new Error(text)}) }) }
Then when I use it, I define how to handle my response and errors as needed at that time:
fetchJSON(url, options) .then((json) => { // do things with the response, like setting state: this.setState({ something: json }) }) .catch(error => { // do things with the error, like logging them: console.error(error) })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With