Javascript .fetch(api) not executing properly for a Python API - javascript

I created a python API which returns based on the input one of three outputs:
"Success (email already exists)"
"Success"
"Invalid Email"
I have atatched what the output looks like when called directly from a browser. So the issue is when I call this API in my code, it doesnt execute switching to another page and keeps showing a error message I created if the API returns "Invalid Email". It shows the error message and doesnt execute even if the API returns "Success". I know the API is working and returning the correct outputs as the API is executing the relative commands on some files. How can I fix this? Here is a snippet from my websites code.
form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(form);
const name = formData.get('name');
const email = formData.get('email');
const apiURL = `http://censored-for-privacy/?name=${name}&email=${email}`;
fetch(apiURL)
.then(response => response.text())
.then(data => {
if (data === 'Success (email already exists)' || data === 'Success') {
window.location.href = 'main.html';
} else if (data === 'Invalid Email') {
errorMessage.style.display = 'block';
form.reset();
}
})
.catch(error => {
console.error('Error:', error);
errorMessage.style.display = 'block';
form.reset();
});
});
I have tested the API and it works well, I tried changing 'main.html' to a url for google still doesnt work. It executes the alternate function.

Related

Showing warning when API returns empty data (Vue.js / Axios)

I am quite new with Vue.js and Axios. I was working on getting and displaying data from the API by search function, and trying to figure out how to display a warning/alert or something that would let the user know API response is empty.
Observed result: App shows the data when there's a match in the search box but does not show anything when there's no exact match
Expected result: When there's no exact match showing a text or alert on the front end to indicate "there is no match"
axios.get(`API LINK HERE`,
{
headers: {
"x-rapidapi-host":"API HOST LINK HERE",
"x-rapidapi-key":"API KEY HERE",
"useQueryString":true
},"params":{
"format":"json",
"date-format":"YYYY-MM-DD",
"name":`${query}`
}
})
.then(response => this.itemData = response.data)
}```
Just check any results using a conditional statement.
.then(response => {if (response.data=="") {// code here to alert user of empty response }})
You can set this.itemData to a message signalling an empty response or use some other method of alerting the user.
I'm not that familiar with Vue.js but I think this is more about javascript and you could do:
axios.get(`API LINK HERE`, { headers: HEADERS})
.then(res => {
if (isEmpty(res.data) {
alert("is empty");
} else {
this.itemData = response.data;
}
})
.catch(error => alert("problem. try later")) // your error handling
if you like more try and catch:
try {
const res = await axios.get(`API LINK HERE`, { headers: HEADERS});
const itemData = res.data;
if (isEmpty(itemData) {
alert("is empty");
} else {
this.itemData = itemData;
}
} catch (error) {
alert("my error handling");
}

Differentiate between redirect/JSON-data in response from fetch API request

i am trying to build a logic at front end to differentiate between the redirect and JSON response, the end goal for this is as, if the response is redirect go to that page and if the response is having data then it will render that data on the page.
Note: it is working fine if the back end send response as either res.redirect or res.json, but i am struggling (as in below code) as when i have to check first as what the response is from back end , i thought as if i can use if else statement at front end to disgusting between res.json and res.respond, i have tried like .then(res.redirect=>{…}).then(res.json=>{}) but it doesn’t look like if i am using the correct logic.
Any suggestions please, thanks :slightly_smiling_face:
Snippet from my front end code is .
const request = new Request("http://localhost:5000/api/newuser", options);
(async () => {
const incomingdata = await fetch(request)
*// below i differetiated the incoming response as if it is res.redirect or res.json data but didnt work*
.then((res.redirect) => {
window.location.href = res.url;
})
.then((res.json) => {
console.log("cannot find data");
})
.catch((err) => console.log("err"));
Snippet from my bank end code is,
connection.query("SELECT * FROM users WHERE email=?;", [x1.Email], function (
err,
results
) {
console.log("74",results, err);
console.log("75",results[0].email);
if (err) throw err;
else {
if (results[0].email && results[0].password) {
console.log("79",results[0].email);
//console.log(results[0]);
if (results[0].password == x1.password)
res.redirect("http://localhost:3000/");
else {
res.json({
data: "invalid password",
});
}
} else res.redirect("http://localhost:3000/about");
}
});
});
For redirect you can check if the HTTP code is in the 300 range, which is provided in res.status. It won't take dot notation, So, you can use
.then(res => {
if(res.status >= 300 && res.status < 400){
// redirect
} else {
return res.json();
}
})
.then(data => {
//handle your json data
});
It would be a syntax error to use a dot in the callback argument like:
.then((res.json) => {
However, it would be possible to deconstruct an object like this:
.then(({ status, json }) => {

How to access DB from a function and only then send a post request?

I need help to integrate a few actions inside a function.
I get a call from PayPal, then i need to :
Access my DB to compare.
If ok send 200 OK
Send the request body back.
Currently - I do (3) only, and it somehow works without (2).
exports.contentServer = functions.https.onRequest((request, response) => {
....
....
if(request.path === paid)
{
if (request.method !== "POST")
response.status(405).send("Method Not Allowed");
else {
let ipnTransactionMessage = request.body;
let formUrlEncodedBody = querystring.stringify(ipnTransactionMessage);
let verificationBody = `cmd=_notify-validate&${formUrlEncodedBody}`;
//______________
//** at this point i need to read a firebase collection and return 200OK , ONLY THEN DO THE POST BELOW
var docRef = admin.firestore().collection('All').doc(ipnTransactionMessage.custom);
docRef.once('value').then(function(snapshot) {
console("our data to compare",snapshot);
res.status(200); // ?
});
//**** how do i do the next only after the previous ?
let options = {
method: 'POST',
uri: "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr",
body: verificationBody
};
return rp(options)
.then(body => {
if (body === "VERIFIED") {
//** we are done here - and this actually works already
})
.then(docReference => {
console.log("Request completed");
return response.send({ result: 'ok' });
})
.catch(error => {
console.log(error);
return response.status(500).send(error);
});
See the comment in the code. After reading my DB and respond with 200 OK , only then i would like to send back the body as I do.
As Doug mentioned the code needs to go in the then clause:
I took a part of your code to shaow where the code to get executed only when firestore answers can go.
//** at this point i need to read a firebase collection and return 200OK , ONLY THEN DO THE POST BELOW
var docRef = admin.firestore().collection('All').doc(ipnTransactionMessage.custom);
docRef.once('value').then(function(snapshot) {
console("our data to compare",snapshot);
res.status(200); //
if(snapshot.exists){
// ---------------------------------
// The code that you want to get executed only
// firestore answers Goes Here
// ---------------------------------
}
});

Firebase response depending on Firestore Query does not work

Depending on whether there is an entry in Cloud Firestore with the correct DocumentId. However, this does not work because my function sends the status 200 before even finishing the query. So how can I get that working?
Here is my code:
access = false;
admin.firebase().collection("tuere").doc(door).collection("eintritt").get().then((snapshot) => {
snapshot.forEach((doc) => {
if(doc.id === uid){
access = true;
console.log("May open door " + uid);
}
});
}).catch((err) => {
console.log(err);
});
res.status(200).send(access);
When I open the Tab in Chrome and let it load "false" appears, but when I wait like 15 Seconds "May open door (uid)" appears in the Logs.
How can I solve this problem and how can i get my function to run faster?
You should send the HTTP response when the promise resolves, so within the then of the query promise: like that:
access = false;
admin.firebase().collection("tuere").doc(door).collection("eintritt").get()
.then((snapshot) => {
snapshot.forEach((doc) => {
if(doc.id === uid){
access = true;
console.log("May open door " + uid);
}
});
res.status(200).send(access);
}).catch((err) => {
console.log(err);
res.status(500).send(err);
});
Also, you should send an HTTP response in case of error, this is why I added res.status(500).send(err); in the catch
I would suggest you look this video from Doug Stevenson: https://www.youtube.com/watch?v=7IkUgCLr5oA
Also there is a point which surprises me: shouln't you use
admin.firestore().collection("tuere").doc(door)....
instead of
admin.firebase().collection("tuere").doc(door)
I have to look in the reference, but I have the feeling that admin.firebase() does not exist.

NodeJS Package: error handling

I have some code that uses an Overwatch API to grab some data. This is what I currently have:
OWoverallStats: (playerName, mode, region) => {
mode = (typeof mode === 'undefined') ? 'competitive' : mode.toLowerCase();
region = (typeof region === 'undefined') ? 'us' : region.toLowerCase();
playerName = playerName.replace('#', '-');
return fetch(`https://owapi.net/api/v3/u/${playerName}/stats`)
.then(res => res.json())
.then(data => {
return data[region].stats[mode].overall_stats;
});
}
This works fine, providing you enter a playerName that actually exists. The code I used to test this is:
core.OWoverallStats('Calvin-1337', 'quickplay', 'eu').then(data => {
console.log(data.tier) // grandmaster
}).catch(e => {
console.log(e);
});
In the actual code, I can check if the error code is 404 (player doesn't exist) but then I don't know what I can do with that. I don't want to throw an error, or console log it as if someone implemented this say into a Discord Bot, I'd want the person using the code to say what they wanted to do with the error.
When fetch has a response, if the status is 404 Simply throw an Error. The caller of your code can then catch it and handle however he likes.
For example, your code:
return fetch(`https://owapi.net/api/v3/u/${playerName}/stats`)
.then((res, meta) => {if (meta.status ===404) throw new Error('NoPlayer')})
The caller of your code:
core.OWoverallStats('Calvin-1337', 'quickplay', 'eu').then(data => {
}).catch(e => {
//this is where he can handle the error flexibly
});
You may see other error handling practices here

Categories

Resources