Async | Can not get my async promise to function - javascript

I'm currently writing a login server function and I cannot figure out why the posmise that I'm making isnt being called
Im using mongodb with mongoose as the backend that is being connected to using the User.findOne which works. I cannot figure out why the bottom console.log for Test and test2 never get fired.
I'm quite new to the promise and async and I can't figure out what im missing
class HandlerGenerator {
login (req, res) {
console.log('debguh1')
let username = req.body.username;
let password = req.body.password;
let checkUsername = "";
let checkPassword = "";
var lData = {
username: req.body.username,
password: req.body.password
};
var myPromise = () => {
return new Promise((resolve, reject) => {
console.log('db2')
User.findOne(lData , function(err, userLogin){
if(err){
console.log(err);
return
}
console.log(userLogin)
checkUsername = userLogin.username;
checkPassword = userLogin.password;
});
});
};
var callMyPromise = async () => {
var result = await (myPromise());
// call code here
console.log("Test1")
resolve(result);
//return result
};
callMyPromise().then(function(result) {
console.log('Test2')
res.json(result);
});
}
}

I guess you are using mongoose for your queries, .exec() is returning a promise.
By making your login method async you can now await the response. But do make sure to wrap an await in a try catch block or HOF, to handle errors / or not found users.
class HandlerGenerator {
async login(req, res) {
let { username, password } = req.body;
let checkUsername = "";
let checkPassword = "";
var lData = {
username
password
};
try {
const userData = await User.findOne(lData).exec();
res.json(userData);
} catch (e) {
// do some error handling in here
}
}
}

Related

NodeJS nedb function not awaiting

Function checkExists is taking too long to execute. Tried to use await async function but had no effect. var exists = await checkExists(data.email); is returning undefined because not awaiting for checkExists.
I have my index.js:
const express = require('express');
const app = express();
require('./private/signUpAPI')(app);
app.listen(80, () => console.log('listening on 80'));
app.use(express.static('public'));
app.use(express.json({limit: '1mb'}));
And my signUpAPI.js:
const DataStore = require('nedb');
const express = require('express');
const database = new DataStore('private/database.db');
database.loadDatabase();
module.exports = function api(app){
app.use(express.json({limit: '1mb'}));
app.post('/signUpAPI', async (request, response) => {
console.log("Sign Up Request received!");
const data = request.body;
var exists = await checkExists(data.email);
console.log(exists)
console.log(data);
console.log("Added to DB");
console.log('-------------------------' + '\n');
database.insert(data);
const testData = {"status": "success"};
response.send(testData);
});
}
async function checkExists(email){
var exists = false;
database.find({"email": email}, async function(err, docs){
if (docs.length > 0){exists = true;}
console.log(docs.length);
return exists;
});
}
this is the node output when running index.js and calling the fetch('/signUpAPI'):
Sign Up Request received!
undefined
{
email: 'a',
username: 'a',
hashPass: 'da180265625ebeaf62f4ee1813bdc28faeaf79f0b2b329290758a1c095111ae8',
salt: 'g8VkTBV$+Bh35K9ns7Zt*9^CH#M=VELSzKUX=H3^+5kpFV=bEbVfXFtF*GGYHOa#'
}
Added to DB
-------------------------
37
I currently have 37 entries in the DB with the same data hence the console.log(docs.length) returning 37.
But this is executing last and appears at the bottom of the console when it should appear at the top.
Use https://www.npmjs.com/package/nedb-promise
so you can use await for database queries and you can change your code like this -
async function checkExists(email) {
const record = await database.findOne({ email });
console.log(record);
if (record) return true;
return false;
}
Functions you want to wait should return a promise in order to wait for response.
You either resolve the promise if the operation result is success or reject with an error.
The flow should like something like this;
async function func1()
{
try
{
var tmp = await func2();
console.log(tmp);
}
catch(err)
{
console.log(err);
}
}
async funcion func2()
{
return new Promise(async function (resolve, reject)
{
if(true)
{
resolve("success");
}
else
{
reject("error");
}
});
}

Having problem getting user by id on endpoints, could someone look at my code and maybe guide me?

So what I am trying to do here is get user by id and then show it but seems like my knowledge is lacking and would be happy if someone could point out the mistakes! Code below:
//routes.js
const routes = require('express').Router();
const dbService = require('./database');
routes.get('/products', async (req,res) => {
try {
const resultat = await dbService.getProducts();
res.json(resultat)
}
catch(error)
{
console.log(error);
}
});
routes.get('/user/:id', async (req,res) => {
try
{
const id = req.params.id
const user = await dbService.getUserId(id);
res.send(user);
console.log(user);
}
catch(error)
{
res.send('error..');
}
});
//database.js
const getUserId = async (data) => {
try
{
const dbCon = await dbPromise;
const user = dbCon.get('SELECT * FROM users WHERE id = (?)', [data.id]);
return user;
}
catch(error)
{
throw error;
}
};

Trying to understand Async/Await

I have an async function 'query' that 'awaits' for the pool.query to return the results.
// db.js
const pool = new pg.Pool({
connectionString: isProduction ? process.env.DATABASE_URL : connectionString,
ssl: isProduction,
});
export const query = async ({ text, values }) => {
const start = Date.now();
try {
const results = await pool.query(text, values);
const duration = Date.now() - start;
logger.info(`executed query: ${text} duration: ${duration} rows: ${results.rowCount}`);
return results.rows;
} catch (e) {
logger.error(`error: ${e}`);
}
};
In another async function getUser() I'm 'awaiting' the query function to finish before returning the data.
// users.js
export const getUser = async (email) => {
const text = `
SELECT (user_id, email) FROM users
WHERE email = $1
`;
const values = [email];
try {
const data = await query({ text, values });
// ^ vscode says above await is doing nothing
return data.rows[0];
} catch (e) {
logger.error(`error: ${e}`);
}
};
Then in yet another async function I'm awaiting the getUser function
// auth.js
export const SignIn = async (email, password) => {
const userRecord = await getUser(email);
if (!userRecord) {
throw new Error('User not registered');
}
logger.silly('Checking password');
const validPassword = await argon2.verify(userRecord.password, password);
if (validPassword) {
logger.silly('Password is valid!');
logger.silly('Generating JWT');
const token = await generateToken(userRecord);
const user = { id: userRecord.id, email: userRecord.email };
return { user, token };
} else {
throw new Error('Invalid Password');
}
};
Inside vsCode I'm getting a warning "await has no effect on the type of this expression." only when 'awaiting' the query function call, but not when 'awaiting' the getUser function call. What am I missing here?
What does query return? If results.rows is a promise then that might explain what you're seeing.

Async-await not working as anticipated. Value is 'undefined' after using await

I'm using socket.io with node js. For the authentication, I'm using middleware in socket.io but the code is not waiting for the middleware to finish its work thus the value is 'undefined'.
Here is the main function.
module.exports = async (server) => {
const io = require('socket.io')(server);
io.on(CONNECTION, async function (socket) {
var email = await authenticateUser(io);
console.log(email); // 'undefined'
user = new User(email);
});
}
Middleware function
async function authenticateUser(io) {
io.use(async (socket, next) => {
const handshakeData = socket.handshake.query;
const token = handshakeData.token;
const Email = await Token.isValid(token);
console.log("Auth ---> " + Email); // here it is fine
return new Promise((res, rej) => {
if (Email) {
res(Email);
} else {
rej();
}
});
});
}
Authtentication function
exports.isValid = async (token) => {
try {
const decoded = jwt.verify(token, JWT_KEY);
console.log(decoded.email) // here it is fine
return decoded.email;
} catch (error) {
return false;
}
}
Thank you!
The promise you are creating inside authenticateUser is not visible to the caller since it is created inside the scope of the function you are passing to io.use().
Instead, try creating the promise one lexical level higher so that it is visible after you are finished with the socket.io event handler:
// middleware function
function authenticateUser(io) {
return new Promise((resolve, reject) => {
io.use(async (socket, next) => {
const handshakeData = socket.handshake.query;
const token = handshakeData.token;
const Email = await Token.isValid(token);
if (Email) {
resolve(Email);
} else {
reject(); // should probably put an error here
}
});
});
}

JavaScript Unable to get value returned from a then() call to another then() call

I am trying to execute this code:
UserSchema.methods.generateAuthToken = function () {
const user = this;
const access = 'auth';
const token = jwt.sign({_id: user._id.toHexString(), access}, 'abc123');
user.tokens.push({access, token});
user.save().then(() => {
return token;
});
};
In my express file, I have following code:
app.post('/users', (req, res) => {
const body = _.pick(req.body, ['email', 'password']);
const user = new User(body);
user.save().then(() => {
return user.generateAuthToken();
}).then((token) => {
res.header('x-auth', token).send(user);
}).catch((err) => {
console.log(err);
res.status(400).send(err);
});
});
The problem is that the token returned from the user.save().then() call in first file never reaches the express code user.generateAuthToken(). What is the reason and how should I solve it?
generateAuthToken has no return statement.
If you want to return the promise that then returns, then you have to do so explicitly.
you need to update your schema to the following:
UserSchema.methods.generateAuthToken = function () {
const user = this;
const access = 'auth';
const token = jwt.sign({_id: user._id.toHexString(), access}, 'abc123');
user.tokens.push({access, token});
user.save().then(() => {
return token;
});
};
The generateAuthToken does not return a Promise in your code

Categories

Resources