compare json result from API response - javascript

I'm trying to send API with axios to check if login creds are correct, and I can't retrieve the result from the API.
the mongodb .find finds the correct row but then i want to compare the result from mongo to the api parameters.
for example:
I send to the API {email:somthing#sms.com, password: somthing} and compare with the row {id..,email:somthing, pass: somthing}
code:
API
export default async function handler(request, response){
try{
const { mongoClient } = await connectedToDatabase();
const db = mongoClient.db("db");
const table = db.collection("users");
const {email,password} = request.body
const result = await table
.find({email})
.limit(1)
.toArray();
if (result[0].password == password){
console.log('pass correct')
}
else{
console.log('false');
}
response.status(200).json(result);
}
catch(e){
console.error(e);
}
}
Request:
const clickLogin = async (e) => {
const registerDetails = {
'email': email,
'password': password
};
e.preventDefault();
const res = await axios ({
method: 'POST',
headers:{ 'Content-Type': 'application/json'},
url: 'api/list',
data: JSON.stringify(registerDetails),
});
if (res.status == 200){
console.log(res);
console.log(res.data[0].NickName);
}
setNickName('');
setEmail('');
setPassword('');
};

I managed to find the value of object by ['key'] and then compared it.
code:
export default async function handler(request, response){
try{
const { mongoClient } = await connectedToDatabase();
const db = mongoClient.db("db");
const table = db.collection("users");
const {Email,password} = request.body
const result = await table
.find({Email})
.limit(1)
.toArray();
console.log(result[0]);
if (result[0] !== undefined){
if(result[0]['password'] === password){
console.log('True welcome!');
response.status(200).json(result);
}
else{
console.log('User/Pass not exist!.');
response.status(400).json({ msg: "Email or Password are not exist!" });
}
}
else{
console.log('User/Pass not exist!.');
response.status(400).json({ msg: "Email or Password are not exist!" });
}
}
catch(e){
console.error(e);
}
}

Related

"Error: Error serializing .customerId returned from getServerSideProps in "/pricing"

I keep trying to call an api from my getServerSideProps function in my Next.js application, but everytime I try to do so I get this error
"Error: Error serializing .customerId returned from getServerSideProps in "/pricing".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value."
This is the code for the Pricing page
const Pricing = ({customerId}) => {
console.log(customerId, 'Customerid Pricing')
return(
<div>
<ProductDisplay customerId={customerId}/>
</div>
)
}
export const getServerSideProps = async (ctx) => {
//create customer variable
let customerId
// Create authenticated Supabase Client
const supabase = createServerSupabaseClient(ctx)
// get the user session from supabase
const { data: { session }, } = await supabase.auth.getSession()
//get the user email from the session
const email = session.user.email
//create stripe customer
const createCustomer = async () => {
let createdCustomer;
let customerAvailable;
try {
const checkCustomer = await stripe.customers.search({
query: `email: '${email}'`
})
createdCustomer = JSON.parse(JSON.stringify(checkCustomer))
customerAvailable = createdCustomer.data
} catch (error) {
console.log(error)
}
if (customerAvailable.length) {
customerId = createdCustomer.data[0].id
} else {
try {
const res = await fetch('/api/create-customer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email
})
})
const newCustomer = await res.json();
customerId = newCustomer.customer.id
} catch (error) {
console.log(error)
}
}
}
if (session) {
createCustomer()
} else {
return{
redirect: {
destination: '/signin',
permanent: false,
}
}
}
return {
props: {
customerId
},
}
}
export default Pricing;
This is the /api/create-customer the fetch function is trying to call
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)
const handler = async (req, res) => {
const {email} = req.body
try {
const customer = await stripe.customers.create({
email: email
});
res.status(200).json({
code: 'customer_created',
customer,
})
} catch (error) {
console.log(error);
res.status(400).json({
code: 'customer_creation_failed',
error: error
})
}
};
export default handler;
please help me, thank you very much.

Getting following error while fetching data in react Uncaught (in promise) TypeError: Failed to fetch

I have create backend using express and mongodb database. I am trying to fetch data in react but getting an error while fetching the data as show. Please can anyone tell what the solution of above error is and how can i fetch data from the backend
const Register = () => {
const [values, setValues] = useState({
name: "",
age: "",
country: "",
email: "",
});
const setData = (e) => {
console.log(e.target.value);
const { name, value } = e.target;
setValues((val) => {
return {
...val,
[name]: value,
};
});
};
const addData = async (e) => {
e.preventDefault();
const { name, age, country, email } = values;
const res = await fetch("/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name,
age,
country,
email,
}),
});
const data = await res.json();
console.log(data);
if (res.status === 404 || !data) {
console.log("Error");
} else {
console.log("Data added successfully");
}
};
Here below is the backend code where the post function is performed.
router.post("/register", async (req, res) => {
const { name, age, country, email } = req.body;
if (!name || !age || !country || !email) {
res.status(404).send("Some data is missing");
}
try {
const preuser = await Crud.findOne({ email: email });
console.log(preuser);
if (preuser) {
res.status(404).send("The user already exists");
} else {
let addUser = new Crud({
name,
age,
country,
email,
});
addUser = await addUser.save();
res.status(201).json(addUser);
console.log(addUser);
}
} catch (error) {
res.status(404).send(error);
}
});
await fetch leads to an exception when the HTTP status is ≥ 400. You must add a try-catch block to handle such exceptions:
try {
const res = await fetch("/register", {...});
} catch(exception) {
// Handle the exception
}
Also, HTTP status 404 should be used when a resource is not found. You use it when a user already exists (where status 400 would be more appropriate) or in case of a database error (when 500 would be more appropriate).

How can I store my JWT Token in localstorage?

userAction.js -> Frontend, Action
export const login = (userID, password) => async (dispatch) => {
try {
dispatch({ type: USER_LOGIN_REQUEST });
const url = "http://localhost:8080/authenticate/";
const config = {
auth: {
username: userID,
password,
},
};
const data = {};
const response = await axios.post(
url,
data,
config,
)
dispatch({ type: USER_LOGIN_SUCCESS, payload: config});
if (response.status === 200) {
// Login succeeded
const token = response.data.token;
console.log("TOKEN\n" + token);
config.token = response.data.token;
console.log(response.data.token);
}
localStorage.setItem("userInfo", JSON.stringify(config) );
}
My login function in REST Server :
exports.login = async (req,res) =>{
const b64auth = (req.headers.authorization || '').split(' ')[1] || '';
const [userID, password] = Buffer.from(b64auth, 'base64').toString().split(':');
const user = await User.findOne({ userID: userID });
if(!user) return res.status(400).send('User not found');
const validPass = await bcrypt.compare(password, user.password);
if(!validPass) return res.status(400).send('Incorrect Password');
//const token = generateToken(user.userID);
let payload = {
userID: user.userID
}
const token = generateToken(userID);
res.header('Authorization', 'Bearer ' + token).json(user);
return token;
}
I generate my token this way :
const generateToken = (_id) => {
console.log('Signing token for ID ', _id);
console.log('Secret key is ', process.env.JWT_KEY);
const token = jwt.sign({ _id}, process.env.JWT_KEY, {
expiresIn: "30d",
});
console.log('Signed token: ', token);
return token;
};
I try to store my token in my "userInfo" State .. but only username and password is displayed not token ..It works before .. but I don´t know why it´s not working anymore ^^ I´m completely at a loss
I hope someone sees the error
my Console gives me the detail:
TOKEN
undefined
You are expecting response.data to be an object. In that case update your API handler to return property token in an object:
exports.login = async (req,res) =>{
const b64auth = (req.headers.authorization || '').split(' ')[1] || '';
const [userID, password] = Buffer.from(b64auth, 'base64').toString().split(':');
const user = await User.findOne({ userID: userID });
if(!user) return res.status(400).send('User not found');
const validPass = await bcrypt.compare(password, user.password);
if(!validPass) return res.status(400).send('Incorrect Password');
//const token = generateToken(user.userID);
let payload = {
userID: user.userID
}
const token = generateToken(userID);
return res.header('Authorization', 'Bearer ' + token).json({ user, token });
}
Hopefully that helps!

How to wait for API response in separate function before continuing execution?

I'm new to JavaScript/NodeJS and am having a hard time understanding what is going on here. I'm writing a function that will perform some action based on the response of an API post request within a separate function. For now, that action is just displaying a message on failure or success.
The below code (inside an app.js file) is simply meant to grab the user inputs, pass them to the login_user function (inside an authenticate.js file), and display a message based on the response from login_user.
const { login_user } = require('./authenticate');
// Other requirements
// App initialization
app.post('/auth', function (req, res) {
let username = req.body.username;
let password = req.body.password;
let response = login_user(username, password);
if (response == 204) {
res.send("Success");
} else {
res.send("Failure");
}
});
The below code (inside authenticate.js) accepts the user input, makes an API call, and returns the status code for the response.
const axios = require('axios');
const querystring = require('querystring');
function login_user(username, password) {
var data = {
j_username: username,
j_password: password
};
axios.post("https://fakeurl.com", querystring.stringify(data))
.then(function (response) {
return response.status;
})
.catch(function (error) {
return response.status;
});
}
module.exports = {
login_user
}
What happens is, once the login_user function is called, the code continues executing and goes straight to the else clause of the if/else statement, always resulting in a failure. I would like to wait for the response to be returned before executing the if/else statement.
I tried using async/await with this configuration...
app.post('/auth', async function (req, res) {
let username = req.body.username;
let password = req.body.password;
let response = await login_user(username, password);
if (response == 204) {
res.send("Success");
} else {
res.send("Failure");
}
});
...but did not have any luck. Did I do this incorrectly?
Try this,
const services = require('./authenticate');
app.post('/auth', async function (req, res) {
try {
let username = req.body.username;
let password = req.body.password;
let response = await services.login_user(username, password);
if (response == 204) {
res.send("Success");
} else {
res.send("Failure");
}
} catch (e) {
return res.status(500).json({ status: 500, message: e.message });
}
});
And,
Inside authenticate.js file
const axios = require('axios');
const querystring = require('querystring');
exports.login_user = async function (username, password) {
try {
let data = {
j_username: username,
j_password: password
};
return axios.post("https://fakeurl.com"`enter code here`, querystring.stringify(data))
.then(function (response) {
return response.status;
})
.catch(function (error) {
return response.status;
});
} catch (e) {
console.log(e);
throw Error(`Failed to evaluate transaction: ${e}`)
}
}
Use Async and await function calls in both the files.
Try this
function login_user(username, password) {
var data = {
j_username: username,
j_password: password
};
return axios.post("https://fakeurl.com", querystring.stringify(data))
.then(function (response) {
return response.status;
})
.catch(function (error) {
return response.status;
});
}
app.post('/auth', async function (req, res) {
let username = req.body.username;
let password = req.body.password;
let response = await login_user(username, password);
if (response == 204) {
res.send("Success");
} else {
res.send("Failure");
}
});
Axios return a promise
For more info you can look at this answer here : Returning data from Axios API

How to Avoid nesting promises?

How could I modify the following code to avoid nesting Promises?
The response of request-promise is needed to be inserted in Firestore.
I would also like to know how to have the jsonresponse available when the Firestore Promise is resolved to send the response.status to the caller aplication.
const functions = require('firebase-functions');
const rp = require('request-promise')
var admin = require("firebase-admin");
var serviceAccount = require("./service_key.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://melitest-5bc38.firebaseio.com"
});
let db = admin.firestore()
exports.customHttpRequest = functions.https.onRequest((request, response) => {
const url = 'https://jsonplaceholder.typicode.com/users'
var options = {
uri: url,
method: "GET",
json: true
};
rp(options).then((jsonresponse) => {
for(var i = 0 ; i < jsonresponse.length; i++){
var obj = jsonresponse[i]
var docid = obj.id
// Warning: Avoid nesting promises.eslint(promise/no-nesting)
db.collection("scrapeusertest").doc(String(docid)).set(obj).then(() =>{
console.log(`Data was upload to firestore and the response was: ${jsonresponse}`)
response.status(200).send(jsonresponse);
}).catch(error =>{
console.log(`Error uploading data Firebase: ${error}`)
});
}
return console.log("Data was send")
})
.catch((err) => {
console.log('Error:', err)
});
return null;
});
Easiest option is to use an async function:
const db = admin.firestore()
exports.customHttpRequest = functions.https.onRequest(async (request, response) => {
const url = 'https://jsonplaceholder.typicode.com/users'
const options = {
uri: url,
method: "GET",
json: true
};
const jsonresponse = await rp(options);
await Promise.all(jsonresponse.map(async obj => {
const docid = obj.id
try {
await db.collection("scrapeusertest").doc(String(docid)).set(obj);
} catch (error) {
console.log(`Error uploading data Firebase: ${error}`);
}
}));
console.log(`Data was upload to firestore and the response was: ${jsonresponse}`);
response.status(200).send(jsonresponse);
});
use promise and used the promise all as this shape
const res= await rp(options);
//should be soure the res is array
await Promise.all(res.map( async item =>{
const id=item.id;
try {
await db.collection("scrapeusertest").doc(String(id)).set(item);
} catch (error) {
//what action when handle wrror
}))})
you can use the res as what you need

Categories

Resources