Sure, here’s the complete code for a CRUD application with Node.js, Express.js, and .hbs templates using a data.json file to store data:
1. Setting up the project
First, we need to set up a Node.js project and install the necessary dependencies:
mkdir crud-app
cd crud-app
npm init
npm install express hbs body-parser
2. Creating the server
Next, we create the server and listen on a port:
const express = require('express');
const app = express();
const port = 3000;
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
3. Creating the data.json file
We create a data.json file and add some initial data:
{
"items": [
{
"id": 1,
"name": "Mandeep",
"email": "mandeep@gmail.com"
},
{
"id": 2,
"name": "John",
"email": "john@gmail.com"
},
{
"id": 3,
"name": "Jerry",
"email": "jerry@gmail.com"
}
]
}
4. Creating the routes
We create the routes for the CRUD functionality:
create ‘index.js’
const express = require('express');
const app = express();
const fs = require('fs');
const bodyParser = require('body-parser')
// Read data from the data.json file
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json());
const data = JSON.parse(fs.readFileSync('data.json'));
app.set('view engine', 'hbs');
const methodOverride = require('method-override');
app.use(methodOverride('_method'));
// Get all users
app.get('/all', (req, res) => {
// res.send(data.users);
res.render('users/index', {
users: data.users,
});
});
app.get('/users', (req, res) => {
// res.send(data.users);
res.render('users/create', {
users: data.users,
});
});
// Get a single user by id
app.get('/users/:id', (req, res) => {
const user = data.users.find(u => u.id === parseInt(req.params.id));
res.render('users/edit', {
user: user,
});
// if (!user) return res.status(404).send('User not found');
// res.json(user);
});
// Create a new user
app.post('/users', (req, res) => {
// res.send(req.body.email);
const newUser = {
id: data.users.length + 1,
email: req.body.email,
name: req.body.name,
};
data.users.push(newUser);
fs.writeFileSync('data.json', JSON.stringify(data));
res.json(newUser);
});
// Update an existing user by id
app.post('/users/:id', (req, res) => {
const user = data.users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).send('User not found');
user.name = req.body.name || user.name;
user.email = req.body.email || user.email;
fs.writeFileSync('data.json', JSON.stringify(data));
res.json(user);
});
// Delete an existing user by id
app.post('/users-delete/:id', (req, res) => {
// res.send('ddd ggg');
const userIndex = data.users.findIndex(u => u.id === parseInt(req.params.id));
if (userIndex === -1) return res.status(404).send('User not found');
data.users.splice(userIndex, 1);
fs.writeFileSync('data.json', JSON.stringify(data));
res.send('User deleted successfully');
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});
5. Creating the views
Finally, we create the views using .hbs templates:
– views/index.hbs
user/index.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>All Users</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>All Users</h1>
<section class="mb-4 mt-3">
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 text-left">
{{#each users}}
<h6 class="links" id="{{@index}}">Name: {{this.name}} , Email:{{this.email}} <a href="/users/{{this.id}}"+>Edit</a> </h6>
<form action="/users-delete/{{this.id}}" method="POST">
<button type="submit">Delete</button>
</form>
{{/each}}
</div>
</div>
</div>
</section>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
user/edit.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Listing</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Users</h1>
<form method="post" action="/users/{{user.id}}">
<input type="hidden" name="_method" value="PUT">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" class="form-control" value="{{user.name}}">
</div>
<div class="form-group">
<label for="email">email:</label>
<input type="text" id="email" name="email" class="form-control" value="{{user.email}}">
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
user/create.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Listing</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Users</h1>
<form id="" method="post" action="/users">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" class="form-control">
</div>
<div class="form-group">
<label for="email">email:</label>
<input type="text" id="email" name="email" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
http://localhost:3000/all
http://localhost:3000/users
and use
http://localhost:3000/users/2