0

I am using the below function within post method. The async-await is used but in transferAmount totalBalance is not updated when I call the function inside the post route. The return from the function is not proper. I need guidance so that it returns the object with updated values.

    async function transferAmount(fromAccountId, toAccountId, amount) {
        const session = await mongoose.startSession();
        const options= {session, new:true}
        let sourceAccount, destinationAccount;
        const BASICSAVNGS_MAX_BALANCE = 1500;
        
        const result = {
            newSrcBalance: 0,
            totalDestBalance:0,
            transferedAt:moment.now()
        }   
        
        
        try {
            session.startTransaction();
            const source= await Account.findByIdAndUpdate(
                {_id:sourceAccount._id},
                {$inc:{balance:-amount}},
                options
            );
        
            if(source.balance <0) {
                // Source account should have the required amount for the transaction to succeed
                const errorMessage='Insufficient Balance with Sender:';          
                throw new ErrorHandler(404,errorMessage);            
            }
            
            const destination = await Account.findByIdAndUpdate(
                {_id:destinationAccount._id},
                {$inc:{balance:amount}},
                options
            ); 

            // The balance in ‘BasicSavings’ account type should never exceed Rs. 50,000
            if((destination.accountType.name === 'BasicSavings') && (destination.balance > BASICSAVNGS_MAX_BALANCE)) {         
                const errorMessage=`Recepient's maximum account limit reached`;
                throw new ErrorHandler(404,errorMessage); 
            }
            await session.commitTransaction();
            result.transferedAt= moment.now() //*UPDATE THE TRANSFER TIMESTAMP
            result.newSrcBalance = source.balance; //*UPDATE THE SOURCE BALANCE
            session.endSession();

            // finding total balance in destination account
            await User.findById(destination.user.id, async function(err,user) {
                if(err) {
                    const errorMessage=`Recepient not found!`;
                    console.log(err);
                    throw new ErrorHandler(404,errorMessage);  
                } else {                
                    if(user.accounts) {
                        await Account.find({
                            '_id' :{$in:user.accounts}
                        }, function(err,userAccounts) {                       
                            totalDestBalance = userAccounts.reduce( (accumulator,obj) => accumulator+obj.balance,0); 
                            result.totalDestBalance = totalDestBalance; //*UPDATE THE TOTAL BALANCE  
                            console.log(result); 
                            return result;                                                                                                              
                        });                    
                    }                
                }
            }); 
                    
        }
        catch (error) {
            // Abort transaction and undo any changes
            await session.abortTransaction();
            session.endSession();
            throw new ErrorHandler(404,error);
        } finally {
            if(session) {
                session.endSession();
            }
        }    
    }

    module.exports = transferAmount;

Result of above function is

{
  newSrcBalance: 940,
  totalDestBalance: 1060,
  transferedAt: 1594982541900
}

But inside the post request below it is {}

const result = await transferAmount(fromAccountId, toAccountId, amount);
Devendra Singh
  • 157
  • 3
  • 5
  • 18
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – CherryDT Jul 17 '20 at 11:09

2 Answers2

1

You are not returning something inside the function. User.findById - this receives a callback for returning something. You can convert it as async/await syntax or have to resolve the result with promise.

Like below:

try {
    const user = await User.findById(destination.user.id);

    if (user.accounts) {
        const userAccounts = await Account.find({ _id: { $in: user.accounts } });
        totalDestBalance = userAccounts.reduce((accumulator, obj) => accumulator + obj.balance, 0);
        result.totalDestBalance = totalDestBalance; //*UPDATE THE TOTAL BALANCE
        console.log(result);
        return result;
    }
} catch (err) {
    const errorMessage = `Recepient not found!`;
    console.log(err);
    throw new ErrorHandler(404, errorMessage);
}

Or:

return new Promise((resolve, reject) => {
    User.findById(destination.user.id, async function(err, user) {
        if (err) {
            const errorMessage = `Recepient not found!`;
            console.log(err);
            reject(err);
        } else {
            if (user.accounts) {
                await Account.find(
                    {
                        _id: { $in: user.accounts },
                    },
                    function(err, userAccounts) {
                        totalDestBalance = userAccounts.reduce((accumulator, obj) => accumulator + obj.balance, 0);
                        result.totalDestBalance = totalDestBalance; //*UPDATE THE TOTAL BALANCE
                        console.log(result);
                        resolve(result);
                    }
                );
            }
        }
    });
});
critrange
  • 5,652
  • 2
  • 16
  • 47
0

I may be wrong but i cannot see a return statement in you transferAmount function.

  • I tried return at end of the function but it returned non updated amount. { "newSrcBalance": 920, "totalDestBalance": 0, "transferedAt": 1594984778470 } but in function it is { newSrcBalance: 920, totalDestBalance: 1080, transferedAt: 1594984778470 } – Devendra Singh Jul 17 '20 at 11:19