Project Structure (Backend)

PROJECT STRUCTURE IMAGE FOR BACKEND

Example: Create the required files as seen on the project structure and add the following codes.

Node
// authController.js

const User = require("../models/User");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");

exports.register = async (req, res) => {
    try {
        const { username, email, password } = req.body;
        let user = await User.findOne({ email });
        if (user) {
            console.log("User already exists:", email);
            return res.status(400).json({ msg: "User already exists" });
        }
        user = new User({
            username,
            email,
            password,
        });
        const salt = await bcrypt.genSalt(10);
        user.password = await bcrypt.hash(password, salt);
        await user.save();
        const token = generateJwtToken(user.id);
        res.json({ token });
    } catch (err) {
        console.error("Error registering user:", err.message);
        res.status(500).send("Server Error");
    }
};

exports.login = async (req, res) => {
    try {
        const { email, password } = req.body;
        const user = await User.findOne({ email });
        if (!user) {
            return res.status(400).json({ msg: "Invalid credentials" });
        }
        const isMatch = await bcrypt.compare(password, user.password);
        if (!isMatch) {
            return res.status(400).json({ msg: "Invalid credentials" });
        }
        const token = generateJwtToken(user.id);
        res.status(200).json({ token });
    } catch (err) {
        console.error("Error logging in user:", err.message);
        res.status(500).send("Server Error");
    }
};

function generateJwtToken(userId) {
    const payload = {
        user: {
            id: userId,
        },
    };
    return jwt.sign(payload, "jwtSecret", { expiresIn: 3600 });
}
Node
// activityController.js

const Activity = require("../models/Activity");
const jwt = require("jsonwebtoken");
const secretKey = "jwtSecret";

exports.getAllActivities = async (req, res) => {
    let userId;
    try {
        jwt.verify(
            req.headers["authorization"].substring(7),
            secretKey,
            (err, decodedToken) => {
                if (err) {
                    console.error("Error decoding token:", err);
                } else {
                    userId = decodedToken.user.id;
                }
            }
        );
        const activities = await Activity.find({ userId: userId });
        res.json(activities);
    } catch (err) {
        console.error(err.message);
        res.status(500).send("Server Error");
    }
};

exports.createActivity = async (req, res) => {
    try {
        let activity = {};
        const { activityName, duration, caloriesBurned, steps, distance, date } =
            req.body;
        if (
            req.headers["authorization"] &&
            req.headers["authorization"].startsWith("Bearer ")
        ) {
            jwt.verify(
                req.headers["authorization"].substring(7),
                secretKey,
                (err, decodedToken) => {
                    if (err) {
                        console.error("Error decoding token:", err);
                    } else {
                        activity = new Activity({
                            userId: decodedToken.user.id,
                            activityName,
                            duration,
                            caloriesBurned,
                            steps,
                            distance,
                            date,
                        });
                    }
                }
            );
            await activity.save();
            res.json(activity);
        }
    } catch (err) {
        console.error(err.message);
        res.status(500).send("Server Error");
    }
};

exports.getActivityById = async (req, res) => {
    try {
        const id = req.params.id;
        const activities = await Activity.findById(id);
        res.json(activities);
    } catch (err) {
        console.error(err.message);
        res.status(500).send("Server Error");
    }
};

exports.updateActivity = async (req, res) => {
    try {
        const { id } = req.params;
        const { activityName, duration, caloriesBurned, steps, distance } =
            req.body;
        const activity = await Activity.findByIdAndUpdate(
            id,
            {
                activityName,
                duration,
                caloriesBurned,
                steps,
                distance,
            },
            { new: true }
        );
        res.json(activity);
    } catch (err) {
        console.error(err.message);
        res.status(500).send("Server Error");
    }
};

exports.deleteActivity = async (req, res) => {
    try {
        const { id } = req.params;
        await Activity.findByIdAndDelete(id);
        res.json({ msg: "Activity deleted" });
    } catch (err) {
        console.error(err.message);
        res.status(500).send("Server Error");
    }
};
Node
// models/Activity.js

const mongoose = require('mongoose');

const activitySchema = new mongoose.Schema({
    userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    activityName: {
        type: String,
        required: true,
    },
    duration: {
        type: Number,
        required: true
    },
    caloriesBurned: {
        type: Number,
        required: true
    },
    steps: {
        type: Number,
        required: false
    },
    distance: {
        type: Number,
        required: false
    },
    date: {
        type: Date,
        default: Date.now
    }
});

module.exports = mongoose.model('Activity', activitySchema);
Node
// models/User.js

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    }
});

module.exports = mongoose.model('User', userSchema);
Node
// routes/activityRoutes.js

const express = require('express');
const router = express.Router();
const activityController = require('../controllers/activityController');

router.get('/', activityController.getAllActivities);

router.post('/create', activityController.createActivity);

router.get('/:id', activityController.getActivityById);

router.put('/update/:id', activityController.updateActivity);

router.delete('/delete/:id', activityController.deleteActivity);

module.exports = router;
Node
// routes/authRoutes.js

const express = require('express');
const router = express.Router();
const authController = require('../controllers/authController');

router.post('/register', authController.register);

router.post('/login', authController.login);

module.exports = router;
Node
// server.js

const express = require('express');
const mongoose = require('mongoose');
const authRoutes = require('./routes/authRoutes');
const activityRoutes = require('./routes/activityRoutes');
const cors = require('cors');

const app = express();
app.use(cors());
app.use(express.json());

mongoose.connect('mongodb://localhost:27017/health-tracker', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    family: 4,
})
    .then(() => console.log('MongoDB Connected'))
    .catch(err => console.log(err));

app.use('/api/auth', authRoutes);
app.use('/api/activities', activityRoutes);

const PORT = 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

To start the backend server use the following command:

nodemon server.js

Step 4: Install the angular CLI

npm install -g @angular/cli

Step 5: Create a new angular project

ng new frontend

Step 6: Create components for various functionalities in angular application

Syntax - ng generate component <component-name>
ng generate component auth
ng generate component activities

Step 7: Create service in frontend to establish communication between frontend and backend

Syntax - ng generate service <service-name>
ng generate service auth
ng generate service activities

The updated dependencies in package.json file of frontend will look like:

"dependencies": {
"@angular/animations": "^17.2.4",
"@angular/common": "^17.2.4",
"@angular/compiler": "^17.2.4",
"@angular/core": "^17.2.4",
"@angular/forms": "^17.2.4",
"@angular/platform-browser": "^17.2.4",
"@angular/platform-browser-dynamic": "^17.2.4",
"@angular/platform-server": "^17.2.4",
"@angular/router": "^17.2.4",
"@angular/ssr": "^17.2.3",
"@auth0/angular-jwt": "^5.2.0",
"express": "^4.18.2",
"jwt-decode": "^4.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.2"
}

Health Tracker using MEAN Stack

In the fast-paced world, maintaining a healthy lifestyle is more important than ever. Technology can play a significant role in helping individuals monitor and improve their health. In this article, we’ll explore how to use the power of the MEAN (MongoDB, Express.js, Angular, Node.js) stack to build a robust and feature-rich Health Tracker application.

Project Preview: Let us have a look at how the final output will look like.

PROJECT PREVIEW IMAGE

Similar Reads

Prerequisites:

AngularJSNodeJSExpressMongoDBMEAN Stack...

Approach to create Health Tracker:

Backend:...

Steps to create the project:

Step 1: Create the main folder for the project which will consist of both backend and frontend...

Project Structure (Backend):

PROJECT STRUCTURE IMAGE FOR BACKEND...

Project Structure (Frontend):

PROJECT STRUCTURE IMAGE FOR FRONTEND...