I'm sending HTTP-requests to a server and when I receive them, I check for the status. If the status isn't 200, I want to throw the response of the server and catch it to do stuff with the error.
const handleRegistration = (nickname, email, password) => {
fetch("https://localhost:44317/api/Authentication/register",
{
method: "POST",
body: JSON.stringify({nickname: nickname, email: email, password: password}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then((response) => {
if (response.status === 200) {
location.href = "../login/login.html";
} else {
throw response.json();
}
})
.catch((response) => {
// Do something
});
};
When I register a new account where all the input fields are valid, the program works fine. But when I input data that makes for the server to return a 400 POST with as Response {"DuplicateUserName":["User name 'blabla' is already taken."]}, then I get TypeError: handleFetch(...) is undefined in my console. I'm not really sure what to do.
I've set breakpoints in the catch statement and noticed that my code never reaches it.
Related
I have a flask api (running on host='0.0.0.0', port=8080, which should cause it to run on my priv ip), and a javascript fetch request, which when called isnt able to reach the api for some reason. The javascript is running in a webpage hosted on http://127.0.0.1:5500. Yes I have tried curl and it works perfectly. The code for the fetch request is
const lbutton = document.getElementById("lbutton");
lbutton.addEventListener("click", function() {
console.log('button clicked');
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
fetch('http://not gonna give out my ip:8080/api/log', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({email: email, password: password})
})
.then(response => {
console.log('Success:', response);
if (response.ok) {
console.log('worked');
} else {
throw new Error('Server response was not OK');
}
})
.catch(error => {
console.error('Error:', error);
});
});
Can someone explain to me why it is not working, I have been trying to figure out how to do this for ages.
I tried to make it send a POST request to my api, which should work and the api should receive login info, but the request is not making it through at all.
The fetch api is making a GET request to http://127.0.0.1:5500/login.html?email=test#gmail.com&password=test
I have been trying to make a login page in reactjs but it's throwing me an error in console like
SyntaxError: Unexpected token r in JSON at position 0 but I got 200 status code in network tab and also I'm getting "redirect" in both response and preview tab under the network tab.
I tried the same code(except it was if(response.ok) this time) with another server of my friend and it successfully redirects it to another page
This is the code that I've been trying: is response.data not correct for reactjs?
performLogin = async () => {
var body = {
password: this.state.password,
email: this.state.email
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(body)
};
const url = "/api/authenticate";
try {
const response = await fetch(url, options);
const result = await response.json();
console.log(response); //nothing is showing in console for this statement
if (response.data == "redirect") {
this.props.history.push(`/verifyOtp/${this.state.email}`);
} else {
console.log("login failed");
window.alert("login failed");
}
} catch (error) {
console.error(error);
}
};
edit: I also tried it in postman and it gives "redirect" as response in postman so the api must be working fine
Your problem is in this line
const result = await response.json();
Your response is ok, everything is ok, but when you try to do response.json() and the response from the request isn't a valid json (maybe just a normal text), it will give you that error.
Because response can be a text or a json, you need to do some checking. Where is how to check if response is a json
This is kind of bad because on every request you will need to do this type of checking (transform it to text, try to parse, bla bla...), so What I recommend it you to use something better than fetch.
Axios is very good because it already do that checking.
For your example:
performLogin = async () => {
var body = {
password: this.state.password,
email: this.state.email
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(body)
};
const url = "/api/authenticate";
try {
const response = await fetch(url, options); // Fetch the resource
const text = await response.text(); // Parse it as text
const data = JSON.parse(text); // Try to parse it as json
// Do your JSON handling here
} catch(err) {
// This probably means your response is text, do you text handling here
}
}
I'm making an application that requires login to an API. I have a login form which sends the ID number and password to the API, and the API should respond like this:
[
{
"user_id":"032984",
"user_number":"140521351",
"token":"990nZtMtEUUMY"
}
]
If there is a login error, the API responds with:
[
{
"ERROR": "INVALID PASSWORD | NOT FOUND 1SELECT user_id, lastname, password, user_number FROM user where user_number = 'INVALIDVALUE'",
},
]
I want to be able to catch a login error with an if statement, like if there is the ERROR object in this JSON, display an alert, else login and save the user_id and token to variables I can use in different screens of the app to send more requests to the API, get those responses in JSON, and show the data I need.
How can I make this happen?
So far, here's the code for my login function:
// login function
_userLogin = () => {
this.setState({ isLoggingIn: true, message: '' });
// send request to API properly
fetch("https://api.company.com/v4/users/json.php", {
method: "POST",
// our headers
headers: {
'Content-Type': 'application/json',
'Connection': 'close',
'Accept': '*/*',
'User-Agent': 'InternalApp/0.1 (InternalApp; ReactNative) Expo/33',
'Accept-Language': 'en-US;q=1.0',
'Accept-Encoding': 'gzip, deflate'
},
// body of the request with number/password
body: JSON.stringify({
user_number: this.state.number,
password: this.state.password,
}),
})
.then(response => {
return response.json(); // make it json?!
}).then(responseData => {
// debug messages
console.log(responseData);
console.log("Moving on to parsing JSON"); // CODE WORKS TO HERE
// parse json
var jsonObj = JSON.parse(responseData); // CODE STUCK HERE
// debug messages
console.log("JSON parsed");
if (jsonObj.ERROR)
console.log("Error caught");
else
this.setState(prevState => ({
credentialJson: prevState.credentialJson = responseData,
isLoggingIn: false,
}))
this.props.onLoginPress();
})
};
I'm really new to React Native and StackOverflow, please excuse any formatting issues with the question. I hope I've provided enough detail.
Based on your comments to this answer and the output of console.log(responseData) your responseData is an Array and your data is an Object inside the first array element. Access your data through responseData[0]. For example:
responseData[0].token
//Should return "990nZtMtEUUMY"
Here is how you would check if there is an error set:
if(responseData[0].ERROR){}
Your fetch library fetch returns a Promise so if the API actually throws an error you can add a catch statement.
fetch(url).then().catch((error) => {
console.log("Error", error);
});
The other thing is the reason your code is halting at JSON.parse is that you already parsed the json in a previous .then clause (response.json()) so your trying to parse an object, not a string, which JSON.parse expects.
I'm trying to implement try/catch on javascript with Fetch API using PATCH Method. Most of the time when the fetch success I get a 400 (Bad Request) error and I don't know why, I wonder If I'm forgetting to add an if statement inside the try statement to check the response status before jumping into the catch statement. I also created a function called retry() to not allow the user to make more than 3 failing calls.
And if I make it fail I am not able to see the numberOfRetries log updated.
const retry = async (callback, numberOfRetries) =>
await callback(numberOfRetries)
export const updateValue = async (name, active, numberOfRetries = 0) => {
try {
await fetch(`${apiUrl}/device/${name}?active=${active}`, {
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-type': 'application/json; charset=UTF-8'
},
body: JSON.stringify({
name,
active
})
})
console.log('ok')
} catch (error) {
if (numberOfRetries >= 2) {
return
}
console.log(`retry number ${numberOfRetries}`)
return await retry(updateValue, ++numberOfRetries)
}
}
when the fetch is successfull I get a 400 (Bad Request) error and I don't know why, it's jumping into the catch statement.
No, the catch block doesn't run. The error you see in the devtools log is because a network request failed with an HTTP error code. You can disable the log messages in the console options.
As for why you are getting a 400 code, you have to check your serverside code - it suggests you are doing the request wrong.
I wonder If I'm forgetting to add an if statement inside the try statement to check the response status
Yes, you forgot that as well. You should check for the .ok property of the response:
export const updateValue = async (name, active, numberOfRetries = 0) => {
try {
const response = await fetch(`${apiUrl}/device/${name}?active=${active}`, {
// ^^^^^^^^^^^^^^
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-type': 'application/json; charset=UTF-8'
},
body: JSON.stringify({
name,
active
})
})
if (response.ok) {
// ^^^^^^^^^^^^^^^^
console.log('ok')
// console.log(await response.text()) or something
} else {
throw new Error("HTTP Error "+response.status);
}
} catch (error) {
if (numberOfRetries >= 2) {
return
// ^^^^^^ should be `throw error` instead of returning undefined?
}
console.log(`retry number ${numberOfRetries}`)
return updateValue(name, active, ++numberOfRetries)
// ^^^^^^^^^^^^^ pretty surely you'll want to pass through the arguments
}
}
I am working on a website where a user should be able to post items to a list. Right now, when I try posting something it comes up with an error saying
Failed to load resource: the server responded with a status of 422 (Unprocessable Entity).
When clicking on it in the console it opens a new tap where it just says
Cannot GET /api/list
Also in the command prompt, it says
Unhandled rejection Error: Can't set headers after they are sent.
Does anybody know why this might be and what I can do to fix it? Here are some snippets of my code:
Index.HTML:
fetch('/api/list', options)
.then(response => response.json())
.then(response => {
if (response.status == 'OK') {
console.log('song is added')
getList(items)
} else {
alert(response.message)
}
})
}
Server.js:
app.post('/api/list', userIsAuthenticated, (req, res) => {
let {
titleArtist
} = req.body
let user_id = req.session.user.id
// seaching for user id in database
let query = {
where: {
userId: user_id
}
}
It might also be somewhere else in the code it goes wrong. Let me know if I should post more snippets of code.
This is because you are making a GET request to POST API.
This is how you can make POST request
fetch(url, {
method: 'POST', // or 'PUT'
body: JSON.stringify(data), // data can be `string` or {object}!
headers:{
'Content-Type': 'application/json'
}
}).then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));