David Nathanael David Nathanael - 2 months ago 17
Node.js Question

proper async/await code node js

Im learning nodejs through building an API, this the registration part.

After trying all existing methods to write async code, i've come to this result. Is this the proper way to do it?

I first thought await/async replace Promise... Do they?

Do I really need to return Promises that way on my 2 functions?

Do I call them that way before returning the result?

import * as db from '../../db';

const addToDatabase = (req) => {
return new Promise((res, rej) => {

db.get().collection('users').insertOne({
req.body
}, (err) => {
if (err) {
rej('Unable to insert to database on registration');
}
else {
res();
}
});
});
};

const checkDuplicate = (req) => {
return new Promise( async (res, rej) => {
let collection = await db.get().collection('users');

collection.find(/* query */).toArray( (err, docs) => {
if (err) {
rej('Unable to check database.');
}
else {
if (docs.length) {
rej('Email/login already used');
}
else {
res();
}
}
});
});
};

const register = async (req, res) => {
try {
await checkDuplicate(req);
await addToDatabase(req);
return res.send({success: true, msg: 'Successful registration'});
} catch(err) {
return res.send({success: false, error: err});
}
};

export default register;


I appreciate your help!

Answer

I first thought await/async replace Promise... Do they?

No, they supplement them. They only replace then calls.

Do I really need to return Promises that way on my 2 functions?

No, in your second function you should not create a promise like that. Never use an async function as a new Promise executor. You should only promisify the toArray method and nothing else. And actually mongodb already returns promises if you don't pass a callback, so you should use

async function addToDatabase(req) {
    try {
        await db.get().collection('users').insertOne({
            req.body
        });
    } catch(err) {
        throw 'Unable to insert to database on registration';
    }
}
async function checkDuplicate(req) {
    let collection = await db.get().collection('users');
    let docs;
    try {
        docs = await collection.find(/* query */).toArray();
    } catch(err) {
        throw 'Unable to check database.';
    }
    if (docs.length) {
        throw 'Email/login already used';
    }
}

Do I call them that way before returning the result?

Yes, your register function is fine.

Comments