The journey of my first big project

Juan Guanipa
Strategio
Published in
4 min readFeb 13, 2023

During my time in IronHack, I had to make a full-web application, using VS code. The requirements were to create an app with a login and sign-up page, create at least two mongoose models, and at least two routes for the user to navigate the web page. For this, I used JavaScript, CSS, and HandleBars.

Maybe you don’t know much about HandleBars since this programming language is not much popular, but it looks a lot like HTML with some other exciting features. HBS and HTML are both primarily classified as Templating Languages, but HBS is a JavaScript-based templating library, you can actually make if/else statements and loop while using HBS. Here is what it looks like on the login page I made:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/{{style}}">
<title>LOG IN</title>
</head>

<body>
<header class="logo">
<h1>PAYMENTAPP</h1>
</header>
<div class="login-wrapper">
<form method="post" action="/login" class="form">
<h2>Log in</h2>
<div class="input-group">
<label>Username</label>
<input type="text" name="username">
</div>
<div class="input-group">
<label>Password</label>
<input type="password" name="password">
</div>
<div class="submit-btn">
<button type="submit">Log in</button>
</div>
{{#if errorMessage}}
<div>
<p style="color: red;">{{errorMessage}}</p>
</div>
{{/if}}
</div>
</form>
</div>
</body>
</body>

</html>

Looks a lot like HTML right? But if you see at the end of the code, I used an if statement with an HBS {{expression}}.

Now, what was my project about? Well, I’m from Venezuela, born and raised in Maracaibo. In Venezuela, payments methods are very irregular, and because of the devaluation of the Bolivar (Venezuela currency) everyone, and I mean EVERYONE uses the USD as currency, but there are no banks that work with USD, so I wanted to make an alternative payment method that everyone could use and use the USD as the main currency in my web application.

So for starters, I made my mongoose models: I made a User model, an Account model, and a Transaction model. Here’s what my user model looks like:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
name: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
accounts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Account'
}]
});



const User = mongoose.model('User', userSchema);

module.exports = User;

Then I had to create the routes, I created an authentication route and a profile route. And for that, we used promises, with promises we could create all the users and store them in the database after we clicked the signup button. The users were created with a name, last name, username, password (encrypted with bcryptjs), and an account with their balance.

My goal was to let users send money to each other using their username (like Venmo or cash app) so I made the program in the profiles routes to make the transactions. If you want to send money first we check if the username of the person receiving it in our database:

router.post('/profile/send-money', (req, res, next) => {
// const currentUser = req.session.user._id;
const sentTo = req.body.sendUsername;

user.find()
.then(foundUser => {
for (let i = 0; i < foundUser.length; i++) {
if (foundUser[i].username === sentTo) {
const receiver = foundUser[i]
res.redirect(`send-money/confirmation/${receiver._id}`)
return;
}
}
res.render('send-money.hbs', { errorMessage: 'Username does not exist' })
})
.catch(err => console.log(err))
})

After that we had to update the balance of both persons, the one sending and the one receiving, and here was where I struggled the most. If you’re familiar with promises, then you know what callback hell is, if not here is a simple explanation: Promises are used in JavaScript to avoid callback hell which is a phenomenon that can occur when using JavaScript nested callbacks and the code can become difficult to read, debug, and maintain. Well since this was my first project, I did not know any better and ended up in callback hell:

router.post('/profile/send-money/confirmation/:userId', (req, res, next) => {
const myBalance = req.body.amount;
const currentAccount = req.body.accountSending;
const receivingAccount = req.body.accountReceiving;

if (myBalance > 0) {

transaction.create({
sendingAccount: currentAccount,
receivingAccount: receivingAccount,
amount: myBalance
})
.then(savedTransaction => {
account.findById(currentAccount)
.then(firstAccount => {
if (firstAccount.balance >= myBalance) {
account.findById(receivingAccount)
.then(secondAccount => {
account.findByIdAndUpdate(firstAccount._id, { $push: { transaction: savedTransaction._id }, balance: Number(firstAccount.balance) - Number(myBalance) }, { new: true })
.then(response => {
console.log('1st response:' + response)
account.findByIdAndUpdate(secondAccount._id, { $push: { transaction: savedTransaction._id }, balance: Number(secondAccount.balance) + Number(myBalance) }, { new: true })
.then(secondResponse => {
console.log('2nd response' + secondResponse)
user.findById(secondAccount.userId)
.then(foundUser => {
console.log('this is the found user: ' + foundUser)
res.render('money-sent.hbs', { savedTransaction, foundUser, myBalance })
})
})
})
})
} else {
res.render('insufficient-founds.hbs', {
BalanceErrorMessage: 'asdf'
})
}
})
})
.catch(err => console.log(err))

So, this actually works perfectly but the code is not easy to read. And this was my most important learning doing this project.

In the end, the app worked perfectly, you can send money and receive money with no problem. The other thing is that it is a demo, no actual money can be sent on the app, you have a deposit page to add money to your balance, and you can type any number that you want and it will be added.

Thanks for taking the time to read my blog, feel free to comment and follow me, and let me know what you think about callback hell and how to avoid it.

--

--