Reactjs isomorphic-fetch PATCH how to have the body error? - javascript

So basically I am sending data with a fetch POST or PATCH method and when I have an error I can see in the network -> response this error:
{
"Errors": [
{
"Code": -201,
"Message": "Could not get file from link",
"AssociatedError": "404 Not Found"
}
],
"Result": null
}
Here is my actual code:
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
} else {
var error = new Error(response.statusText);
error.response = response;
throw error;
}
}
export function sendImageUploaded(data, valueMethod, endpoint) {
return dispatch => {
dispatch(requestPosts(data));
return fetch(endpoint, {
method: valueMethod,
headers: new Headers({
Authorization: Isengard.config.token
}),
body: data
})
.then(checkStatus)
.then(reponse => {
dispatch(successSent("The output list has been successfully sent!"));
}).catch(err => {
console.log('request failed', err);
dispatch(failSent("Error on sending request: " + err));
});
};
};
And I am struggling on having this error message.

You already got your response error in "error.response". You only have to resolve that promise.
instead of
.catch(err => {
console.log('request failed', err);
dispatch(failSent("Error on sending request: " + err));
});
use
.catch(err => {
err.response.json().then((json) =>{
let {Errors,Result} = json;
dispatch(failSent(Errors)); // You are sending your array of errors here
});
});

Related

How to mutate in SWR with query parameters such page after success patch request?

onSubmit={async (values, actions) => {
const { birthdate, ...userData } = values;
let formattedBirthDate = formatDate(birthdate);
const updateUserUrl = `/api/users/update/${id}`;
try {
// send a request to the API to update the source
const res = await api.patch(
updateUserUrl,
{
...userData,
birthdate: formattedBirthDate,
},
{ headers: { "Auth-Token": authToken } }
);
if (res && res.data) {
mutate('api/users?page=1&limit=10',{ ...user, userData, birthdate: formattedBirthDate });
router.replace("/admin?page=1&limit=10");
toast.success("Updated successfully");
}
} catch (error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
toast.error(error.response.data.message);
console.log("Error response data: ", error.response.data);
console.log("Error response status: ", error.response.status);
console.log(
"Error response headers: ,",
error.response.headers
);
} else {
console.log("Error entity error: ", error.message);
toast.error(error.message);
}
}
I am trying to mutate the table data to have an updated data but it won't work if the mutate URL is not correct. If the current data fetch is from page 2, then the mutate URL will be api/users?page=2&limit=10. How can I know if the current data is from page =2?

How to solve this JSON promise error with ReactJS?

I am new to React so there might be a lot of mistakes around. Also, I know there are similar questions, but none helped with my problem so far.
I'm working on a project (using a template) that is using Java Spring (back-end) and ReactJS (front-end).
At the moment I am trying to make a login form, and verify the credentials.
These are the functions that I use when I press Login:
onSubmit(){
let login = {
username: this.state.username,
password: this.state.password
};
this.checkLogin(login);
}
checkLogin(login){
return this.sendRequest(login, (result, status) => {
console.log("AICI NU AJUNG CRED");
if (result !== null && (status === 200 || status === 201)) {
console.log("Successfully inserted person with id: " + result);
this.reloadHandler();
} else {
console.log("There was an error " + result);
}
});
}
sendRequest(login, callback){
let request = new Request(HOST.backend_api + endpoint.login + "/login", {
method: 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(login)
});
console.log(request.url);
console.log(login);
RestApiClient.performRequest(request, callback);
}
function performRequest(request, callback){
fetch(request)
.then(
function(response) {
if (response.ok) {
response.json().then(json => callback(json, response.status,null));
}
else {
response.json().then(err => callback(null, response.status, err));
}
})
.catch(function (err) {
//catch any other unexpected error, and set custom code for error = 1
callback(null, 1, err)
});
}
I try it with a "test" username and "test" password I have in my database.
And this is the result:
dev console result 1
dev console result 2

Error using Axios, but correct response in Postman

I'm having a problem using Axios with my backend. It's probably a very simple fix as I'm new to this.
Postman: The correct response is received for both valid and invalid credentials.
Axios: The correct response is received for valid crendentials, but the axios method's catch block is run when invalid credentials are entered.
authController.js:
exports.login = (req, res, next) => {
const email = req.body.email;
const pass = req.body.password;
let loadedUser;
User.findOne({ where: { email: email } })
.then(user => {
if(!user) {
const error = new Error('Incorrect username or password');
error.statusCode = 401;
throw error;
} else {
loadedUser = user;
return bcrypt.compare(pass, user.password);
}
})
.then(isEqual => {
if(!isEqual) {
const error = new Error('Incorrect username or password');
error.statusCode = 401;
throw error;
} else {
const token = jwt.sign(
{
email: loadedUser.email,
userId: loadedUser.id
},
process.env.JWT_SECRET,
{ expiresIn: '1hr' }
);
res.status(200).json({ token: token, userId: loadedUser.id });
}
})
.catch(err => {
if (!err.statusCode)
err.statusCode = 500;
next(err);
});
};
The error handler in app.js. It seems to log the error correctly when incorrect credentials are entered, even with axios:
app.use((error, req, res, next) => {
const status = error.statusCode || 500;
const message = error.message;
const data = error.data || 'No Data';
console.log(status, message, data);
res.status(status).json({message: message, data: data});
});
But then the axios catch block runs, so instead of receiving the json message, I get the following error
login(email, password) {
const headers = {
'Content-Type': 'application/json'
};
const data = JSON.stringify({
email: email,
password: password
});
axios.post('http://127.0.0.1:8080/auth/login', data, { headers })
.then(res => console.log(res))
.catch(err => console.log(err));
}
The error in the console for invalid credentials:
Clicking the link highlighted opens a new page stating: "Cannot GET /auth/login", but I'm obviously making a post request, & I've added post to the form (just in case)
Any ideas what I could be missing?
Thanks
Actually your code works fine but Axios will reject the promise of the call if you have the status 401. If you have a status between 200 to 300 it will resolve the promise.
There two ways to deal with this.
Check status in the catch block.
axios.post('http://127.0.0.1:8080/auth/login', data, {
headers
})
.then(res => console.log(res))
.catch(err => {
if (err.response.status === 401) {
//Auth failed
//Call reentry function
return;
}
return console.log(err)
});
or change the validateStatus option;
axios.post('http://127.0.0.1:8080/auth/login', data, {
headers,
validateStatus: function (status) {
return status >= 200 && status < 300 || (status === 401);
},
})
.then(res => console.log(res))
.catch(err => return console.log(err));

HTTP request not working when done in code

I am making a request and everything is correct but the issue I have is I keep getting a 404 error. but if I copy the parameters and body with that same url to postman it returns a success. I do not know what I am doing wrong.
const promisify = require('util').promisify;
const { post, get, del } = require('request');
const postAsync = promisify(post);
post: async (url, payload) => {
console.log('USER ID PAYLOAD',payload)
return postAsync(url, {
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
json: true,
body: payload
})
.then(response => {
console.log('USER ID StAtUS CODE', response.url, response.body)
if (response.statusCode >= 400) throw new Error(response.body.message || "An error occurred");
if (response.body && response.body.status === 'error' || response.body.status === 'fail') throw new Error(response.body.message || "An error occurred");
return response.body;
}, error => {
throw error;
})
},

How to wrap JavaScript fetch in a function - unhandled promise rejection

I'm trying to write a wrapper function for the JavaScript fetch command.
I took the example code from this post:
function fetchAPI(url, data, method = 'POST') {
const headers = {
'Authorization': `Token ${getAuthToken()}`,
};
return fetch(url, { headers, 'method': method, 'body': data })
.then(response => {
if (response.ok) {
const contentType = response.headers.get('Content-Type') || '';
if (contentType.includes('application/json')) {
return response.json().catch(error => {
return Promise.reject(new Error('Invalid JSON: ' + error.message));
});
}
if (contentType.includes('text/html')) {
return response.text().then(html => {
return {
'page_type': 'generic',
'html': html
};
}).catch(error => {
return Promise.reject(new Error('HTML error: ' + error.message));
});
}
return Promise.reject(new Error('Invalid content type: ' + contentType));
}
if (response.status === 404) {
return Promise.reject(new Error('Page not found: ' + url));
}
return response.json().then(res => {
// if the response is ok but the server rejected the request, e.g. because of a wrong password, we want to display the reason
// the information is contained in the json()
// there may be more than one error
let errors = [];
Object.keys(res).forEach((key) => {
errors.push(`${key}: ${res[key]}`);
});
return Promise.reject(new Error(errors)
);
});
}).catch(error => {
return Promise.reject(new Error(error.message));
});
};
And I'm calling it like this:
fetchAPI('/api/v1/rest-auth/password/change/', formData).then(response => {
console.log('response ', response);
});
Edit: I have modified the code to display information returned by the server if the request is ok but refused, for example because of an invalid password. You have to interrogate the response json if ok == false.
A valid URL fetch is fine. But if there is an error, I see an Unhandled Rejection (Error): error message.
Why is it that the rejects are unhandled even though they are in catch blocks? What's the secret sauce here?
The way to avoid an unhandled promise rejection, is to handle it:
fetchAPI('/api/v1/rest-auth/password/change/', formData).then(response => {
console.log('response ', response);
}).catch(error => {
// do something meaningful here.
});;

Categories