Open In App

Quiz App using MERN Stack

Last Updated : 04 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we’ll walk through the step-by-step process of creating a complete quiz application with MongoDB, ReactJS, ExpressJS, and NodeJS. This application will provide users with a user-friendly interface for taking and submitting quizzes and a scoreboard to check their standing among others.

Screenshot-2024-02-26-060558

Prerequisites:

Approach to Create a Quiz App with MERN Stack:

Backend:

  • Set up a new NodeJS project with npm or yarn and initialize a Git repository.
  • Use dotenv to manage environment variables. Set up MongoDB Atlas for cloud hosting. Configure environment variables for MongoDB connection URI and application port. Install Express, Mongoose, and cors.
  • Create a new express application and set up middleware. Define API routes for handling data requests. Implement CRUD operations for questions and results data.
  • Define MongoDB schemas for Question and Result models. Create Mongoose models to interact with the MongoDB database.
  • Implement controller functions for handling business logic. Interact with the MongoDB database using the Mongoose models and return responses to clients.
  • Configure the application to listen on the defined port. Start the server. Use nodemon for automatic server restarts during development.

React Frontend:

  • Set up a new React project with create-react-app. Initialize a Git repository. Define the project structure.
  • Install react-router-dom for client-side routing. Set up routes for pages/component
  • Install redux, react-redux, and redux-thunk. Define actions, reducers, and the store for state management.
  • Use Axios or Fetch API to fetch data from backend endpoints. Implement logic for loading, error, and success states during data fetching.
  • Define UI components for rendering the quiz questions, results, and other elements. Use Bootstrap or CSS frameworks for styling.
  • Implement functionalities like starting the quiz, answering questions, navigating, and displaying results. Handle user input, form submission, and button clicks.

Steps to Create the Backend Server:

Step 1: Create a directory for the project.

mkdir server
cd server

Step 2: Initialized the Express app and installing the required packages

npm init -y

Step 3: Install the necessary package in your server using the following command.

npm i express mongoose cors dotenv mongoose morgan nodemon

Project Structure:

Screenshot-2024-03-01-134902

Backend Folder Structure

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

"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.18.2",
"mongoose": "^8.2.0",
"morgan": "^1.10.0",
"nodemon": "^3.1.0"
}

Example: Create the required files and write the following code.

Javascript




// server.js
 
import express from 'express';
import morgan from 'morgan';
import cors from 'cors';
import { config } from 'dotenv';
import router from './router/route.js';
import connect from './database/conn.js';
 
config();
 
const app = express();
 
app.use(morgan('tiny'));
app.use(cors());
app.use(express.json());
 
const port = process.env.PORT || 8080;
 
app.use('/api', router);
 
app.get('/', (req, res) => {
    try {
        res.json("Get Request")
    } catch (error) {
        res.json(error)
    }
});
 
connect().then(() => {
    app.listen(port, () => {
        console.log(`Server connected to http://localhost:${port}`);
    });
}).catch(error => {
    console.log("Invalid Database Connection");
});


Javascript




// controller.js
 
import Questions from "../models/questionSchema.js";
import Results from "../models/resultSchema.js";
import questions, { answers } from '../database/data.js'
 
/** get all questions */
export async function getQuestions(req, res) {
    try {
        let q = await Questions.find();
        if (q.length === 0) {
            await Questions.insertMany({ questions, answers });
            q = await Questions.find();
        }
        res.json(q);
    } catch (error) {
        res.json({ error });
    }
}
 
/** insert all questinos */
export async function insertQuestions(req, res){
    try {
        Questions.insertMany({ questions: questions, answers: answers })
    } catch (error) {
        res.json({ error })
    }
}
 
/** Delete all Questions */
export async function dropQuestions(req, res){
   try {
        await Questions.deleteMany();
        res.json({ msg: "Questions Deleted Successfully...!"});
   } catch (error) {
        res.json({ error })
   }
}
 
/** get all result */
export async function getResult(req, res){
    try {
        const r = await Results.find();
        res.json(r)
    } catch (error) {
        res.json({ error })
    }
}
 
/** post all result */
export async function storeResult(req, res) {
    try {
        const { username, result, attempts, points, achived } = req.body;
        if (!username && !result) throw new Error('Data Not Provided...!');
 
        const newResult = await Results.create({ username, result, attempts, points, achived });
        res.json({ msg: "Result Saved Successfully...!", result: newResult });
 
    } catch (error) {
        res.json({ error });
    }
}
 
/** delete all result */
export async function dropResult(req, res){
    try {
        await Results.deleteMany();
        res.json({ msg : "Result Deleted Successfully...!"})
    } catch (error) {
        res.json({ error })
    }
}


Javascript




// conn.js
 
import mongoose from "mongoose";
 
export default async function connect(){
    await mongoose.connect(process.env.ATLAS_URI)
    console.log("Database Connected")
}


Javascript




// data.js
 
export default [
    {
        id: 1,
        question : "Javascript is an _______ language",
        options : [
            'Object-Oriented',
            'Object-Based',
            'Procedural',
        ]
    },
    {
        id: 2,
        question : "Following methods can be used to display data in some form using Javascript",
        options : [
            'document.write()',
            'console.log()',
            'window.alert()',
        ]
    },
    {
        id: 3,
        question : "When an operator value is NULL, the typeof returned by the unary operator is:",
        options : [
            'Boolean',
            'Undefined',
            'Object',
        ]
    },
    {
        id: 4,
        question : "What does the toString() method return?",
        options : [
            'Return Object',
            'Return String',
            'Return Integer'
        ]
    },
    {
        id: 5,
        question : "Which function is used to serialize an object into a JSON string?",
        options : [
            'stringify()',
            'parse()',
            'convert()',
        ]
    }
];
 
export const answers = [0, 1, 2, 1, 0];


Javascript




// questionSchema.js
 
import mongoose from "mongoose";
const { Schema } = mongoose;
 
/** question model */
const questionModel = new Schema({
    questions: { type : Array, default: []}, // create question with [] default value
    answers : { type : Array, default: []},
    createdAt: { type: Date, default: Date.now },
});
 
export default mongoose.model('Question', questionModel);


Javascript




// resultSchema.js
 
import mongoose from "mongoose";
const { Schema } = mongoose;
 
 
/** result model */
const resultModel = new Schema({
    username : { type : String },
    result : { type : Array, default : []},
    attempts : { type : Number, default : 0},
    points : { type : Number, default : 0},
    achived : { type : String, default : ''},
    createdAt : { type : Date, default : Date.now}
})
 
export default mongoose.model('result', resultModel);


Javascript




// route.js
 
import { Router } from "express";
import * as controller from '../controllers/controller.js';
 
const router = Router();
 
router.route('/')
 
router.route('/questions')
        .get(controller.getQuestions)
        .post(controller.insertQuestions)
        .delete(controller.dropQuestions);
 
router.route('/result')
        .get(controller.getResult)
        .post(controller.storeResult)
        .delete(controller.dropResult);
 
export default router;


Steps to Setup Frontend with React

Step 1: Create React App

npx create-react-app client

Step 2: Switch to the project directory

cd client

Step 3: Installing the required packages:

npm install react-redux react-router-dom axios nodemon @reduxjs/toolkit 

Step 4: Create a folder inside the src folder i.e. components, helper, hooks, and redux. Inside component create App.js, Main.js, Question.js, Quiz.js, Result.js, ResultTable.js. Inside helper create helper.js, in the hooks folder create FetchQuestion.js, setResult.js and inside the redux folder create question_reducer.js, result_reducer.js, store.js.

Project Structure:

Screenshot-2024-03-01-134615

Frontend Folder Structure

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

"dependencies": {
"@reduxjs/toolkit": "^2.2.1",
"axios": "^1.6.7",
"nodemon": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^9.1.0",
"react-router-dom": "^6.22.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},

Example: Create the required files and write the following code.

CSS




/* App.css */
 
 
:root{
  --primary-color: #0DFF92;
  --dark-color:#222222;
  --light-color: #f0f0f0;
}
 
body, html{
  height: 100%;
  background: var(--dark-color)
}
 
* > *{
    font-family: 'Poppins', sans-serif;
}
 
.container{
  display: block;
  position: relative;
  margin: 40px auto;
  height: auto;
  width: 800px;
  padding: 20px;
}
 
.container .title{
    font-size: 3em;
    text-align: center;
    border: 5px solid var(--primary-color);
    padding: .3em .2em;
    border-radius: 4px;
}
 
.text-light {
    color: var(--light-color)
}
 
.container ul{
  list-style: none;
  margin: 0;
  padding: 0;
    overflow: auto;
}
 
.container .questions{
    padding: 3em;
}
 
/*
.container .questions .qid{
  padding: .2em .7em;
  color: #222222;
  background-color: #0DFF92;
  border-radius: 50px;
} */
 
.container .grid{
    margin-top: 3em;
    display: grid;
    grid-template-columns: 1fr 1fr;
}
 
 
.container .btn{
    padding: .2em 1.7em;
    border: none;
    border-radius: .1em;
    font-size: 1.2em;
}
 
.container .btn:hover{
    cursor: pointer;
    background-color: #f0f0f0;
    color: #202020;
}
 
.next{
    background-color: var(--primary-color);
    justify-self: flex-end;
}
 
.prev{
    background-color: #faff5a;
    justify-self: flex-start;
}
 
ul li{
  color: #AAAAAA;
  display: block;
  position: relative;
  float: left;
  width: 100%;
  height: 100px;
    border-bottom: 1px solid #333;
}
 
ul li input[type=radio]{
  position: absolute;
  visibility: hidden;
}
 
ul li label{
  display: block;
  position: relative;
  font-weight: 300;
  font-size: 1.35em;
  padding: 25px 25px 25px 80px;
  margin: 10px auto;
  height: 30px;
  z-index: 9;
  cursor: pointer;
  -webkit-transition: all 0.25s linear;
}
 
ul li:hover label{
    color: #FFFFFF;
}
 
ul li .check{
  display: block;
  position: absolute;
  border: 5px solid #AAAAAA;
  border-radius: 100%;
  height: 25px;
  width: 25px;
  top: 30px;
  left: 20px;
    z-index: 5;
    transition: border .25s linear;
    -webkit-transition: border .25s linear;
}
 
ul li:hover .checked {
  border: 5px solid #FFFFFF;
}
 
ul li .check::before {
  display: block;
  position: absolute;
    content: '';
  border-radius: 100%;
  height: 15px;
  width: 15px;
  top: 5px;
    left: 5px;
  margin: auto;
    transition: background 0.25s linear;
    -webkit-transition: background 0.25s linear;
}
 
 
input[type=radio]:checked ~ .check {
  border: 5px solid var(--primary-color)
}
 
input[type=radio]:checked ~ .check::before{
  background: var(--primary-color)
}
 
input[type=radio]:checked ~ .text-primary{
  color: var(--primary-color)
}
 
/* To get selected option we are using this checked class */
.checked {
  border: 5px solid var(--primary-color) !important;
}
 
.checked::before{
  background: var(--primary-color)
}


CSS




/* index.css */
 
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
 
code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}


CSS




/* Main.css */
 
.container ol li {
  font-size: 1.4em;
  color: #cecece;
}
 
.start {
  display: flex;
  justify-content: center;
  padding-top: 2em;
}
 
.start .btn {
  padding: .2em 1.7em;
  border: none;
  border-radius: .1em;
  font-size: 1.2em;
  color: #202020;
  text-decoration: none;
  background-color: #faff5a;
}
 
#form {
  display: flex;
  justify-content: center;
  margin-top: 4em;
}
 
#form .userid {
  padding: .7em 2em;
  width: 50%;
  border: none;
  border-radius: 3px;
  font-size: 1em;
}


CSS




/* Result.css */
 
.flex-center {
  display: flex;
  justify-content: center;
  flex-direction: column;
  border: 1px solid #cecece;
  padding: 3em 4em;
  gap: 1em;
}
 
.container .flex {
  display: flex;
  justify-content: space-between;
 
}
 
.container .flex span {
  font-size: 1.4em;
  color: #cecece;
}
 
.container .flex span.achive {
  font-weight: bold;
  color: #ff2a66;
  color: #2aff95;
}
 
table {
  width: 100%;
}
 
.table-header {
  color: #cecece;
  font-size: 1.1em;
  text-align: center;
  background: #212121;
  padding: 18px 0;
}
 
.table-body {
  font-size: 1.1em;
  text-align: center;
  /* color: #cecece; */
  background: #d8d8d8;
  padding: 18px 0;
}
 
.table-header>tr>td {
  border: 1px solid #faff5a;
}


Javascript




// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import App from './components/App';
 
 
/** Redux Store */
import store from './redux/store';
import { Provider } from 'react-redux';
 
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store}>
        <App />
    </Provider>
);


Javascript




// Result.js
 
import React, { useEffect } from 'react'
import '../styles/Result.css';
import { Link } from 'react-router-dom';
 
import ResultTable from './ResultTable';
import {
    useDispatch,
    useSelector
} from 'react-redux';
import {
    attempts_Number,
    earnPoints_Number,
    flagResult
} from '../helper/helper';
 
/** import actions  */
import {
    resetAllAction
} from '../redux/question_reducer';
import {
    resetResultAction
} from '../redux/result_reducer';
import {
    usePublishResult
} from '../hooks/setResult';
 
 
export default function Result() {
 
    const dispatch = useDispatch()
    const { questions: { queue, answers }, result:
        { result, userId } } = useSelector(state => state)
 
    const totalPoints = queue.length * 10;
    const attempts = attempts_Number(result);
    const earnPoints = earnPoints_Number(result, answers, 10)
    const flag = flagResult(totalPoints, earnPoints)
 
 
    /** store user result */
    usePublishResult({
        result,
        username: userId,
        attempts,
        points: earnPoints,
        achived: flag ? "Passed" : "Failed"
    });
 
    function onRestart() {
        dispatch(resetAllAction())
        dispatch(resetResultAction())
    }
 
    return (
        <div className='container'>
            <h1 className='title text-light'>Quiz Application</h1>
 
            <div className='result flex-center'>
                <div className='flex'>
                    <span>Username</span>
                    <span className='bold'>{userId || ""}</span>
                </div>
                <div className='flex'>
                    <span>Total Quiz Points : </span>
                    <span className='bold'>{totalPoints || 0}</span>
                </div>
                <div className='flex'>
                    <span>Total Questions : </span>
                    <span className='bold'>{queue.length || 0}</span>
                </div>
                <div className='flex'>
                    <span>Total Attempts : </span>
                    <span className='bold'>{attempts || 0}</span>
                </div>
                <div className='flex'>
                    <span>Total Earn Points : </span>
                    <span className='bold'>{earnPoints || 0}</span>
                </div>
                <div className='flex'>
                    <span>Quiz Result</span>
                    <span style={{ color: `${flag ? "#2aff95" : "#ff2a66"}` }}
                        className='bold'>{flag ? "Passed" : "Failed"}</span>
                </div>
            </div>
 
            <div className="start">
                <Link className='btn' to={'/'}
                    onClick={onRestart}>Restart</Link>
            </div>
 
            <div className="container">
                {/* result table */}
                <ResultTable></ResultTable>
            </div>
        </div>
    )
}


Javascript




// Questions.js
 
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
 
 
/** Custom Hook */
import { useFetchQestion } from '../hooks/FetchQuestion'
import { updateResult } from '../hooks/setResult'
 
 
export default function Questions({ onChecked }) {
 
    const [checked, setChecked] = useState(undefined)
    const { trace } = useSelector(state => state.questions);
    const result = useSelector(state => state.result.result);
    const [{ isLoading, apiData, serverError }] = useFetchQestion()
 
    const questions = useSelector(state =>
        state.questions.queue[state.questions.trace])
    const dispatch = useDispatch()
 
    useEffect(() => {
        dispatch(updateResult({ trace, checked }))
    }, [checked])
 
    function onSelect(i) {
        onChecked(i)
        setChecked(i)
        dispatch(updateResult({ trace, checked }))
    }
 
 
    if (isLoading) return <h3 className='text-light'>isLoading</h3>
    if (serverError) return
    <h3 className='text-light'>
        {serverError || "Unknown Error"}
    </h3>
 
    return (
        <div className='questions'>
            <h2 className='text-light'>{questions?.question}</h2>
 
            <ul key={questions?.id}>
                {
                    questions?.options.map((q, i) => (
                        <li key={i}>
                            <input
                                type="radio"
                                value={false}
                                name="options"
                                id={`q${i}-option`}
                                onChange={() => onSelect(i)}
                            />
 
                            <label className='text-primary'
                                htmlFor={`q${i}-option`}>{q}</label>
                            <div className={
                                `check ${result[trace] == i ? 'checked' : ''}`}>
                            </div>
                        </li>
                    ))
                }
            </ul>
        </div>
    )
}


Javascript




// ResultTable.js
 
import React, { useEffect, useState } from 'react'
import { getServerData } from '../helper/helper'
 
export default function ResultTable() {
 
    const [data, setData] = useState([])
 
    useEffect(() => {
        getServerData(`
        ${process.env.REACT_APP_SERVER_HOSTNAME}/api/result`, (res) => {
            setData(res)
        })
    })
 
    return (
        <div>
            <table>
                <thead className='table-header'>
                    <tr className='table-row'>
                        <td>Name</td>
                        <td>Attemps</td>
                        <td>Earn Points</td>
                        <td>Result</td>
                    </tr>
                </thead>
                <tbody>
                    {!data ?? <div>No Data Found </div>}
                    {
                        data.map((v, i) => (
                            <tr className='table-body' key={i}>
                                <td>{v?.username || ''}</td>
                                <td>{v?.attempts || 0}</td>
                                <td>{v?.points || 0}</td>
                                <td>{v?.achived || ""}</td>
                            </tr>
                        ))
                    }
 
                </tbody>
            </table>
        </div>
    )
}


Javascript




// helper.js
 
import { useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
import axios from 'axios'
 
export function attempts_Number(result) {
    return result.filter(r => r !== undefined).length;
}
 
export function earnPoints_Number(result, answers, point) {
    return result.map((element, i) =>
        answers[i] === element).filter(i => i).map(i => point).reduce(
            (prev, curr) => prev + curr, 0);
}
 
export function flagResult(totalPoints, earnPoints) {
    return (totalPoints * 50 / 100) < earnPoints; /** earn 50% marks */
}
 
/** check user auth  */
export function CheckUserExist({ children }) {
    const auth = useSelector(state => state.result.userId)
    return auth ? children :
        <Navigate to={'/'} replace={true}></Navigate>
}
 
/** get server data */
export async function getServerData(url, callback) {
    const data = await (await axios.get(url))?.data;
    return callback ? callback(data) : data;
}
 
 
/** post server data */
export async function postServerData(url, result, callback) {
    const data = await (await axios.post(url, result))?.data;
    return callback ? callback(data) : data;
}


Javascript




// FetchQuestion.js
 
import { useEffect, useState } from "react"
import { useDispatch } from "react-redux";
import { getServerData } from "../helper/helper";
 
/** redux actions */
import * as Action from '../redux/question_reducer'
 
/*
 fetch question hook to fetch api data and set value to store
 */
export const useFetchQestion = () => {
    const dispatch = useDispatch();
    const [getData, setGetData] = useState({
        isLoading: false,
        apiData: [], serverError: null
    });
 
    useEffect(() => {
        setGetData(prev => ({ ...prev, isLoading: true }));
 
        /** async function fetch backend data */
        (async () => {
            try {
                const [{ questions, answers }] = await getServerData(`
                ${process.env.REACT_APP_SERVER_HOSTNAME}/api/questions`,
                    (data) => data)
 
                if (questions.length > 0) {
                    setGetData(prev => ({ ...prev, isLoading: false }));
                    setGetData(prev => ({ ...prev, apiData: questions }));
 
                    /** dispatch an action */
                    dispatch(Action.startExamAction({
                        question: questions, answers
                    }))
 
                } else {
                    throw new Error("No Question Avalibale");
                }
            } catch (error) {
                setGetData(prev => ({ ...prev, isLoading: false }));
                setGetData(prev => ({ ...prev, serverError: error }));
            }
        })();
    }, [dispatch]);
 
    return [getData, setGetData];
}
 
 
/** MoveAction Dispatch function */
export const MoveNextQuestion = () => async (dispatch) => {
    try {
        dispatch(Action.moveNextAction()); /** increase trace by 1 */
    } catch (error) {
        console.log(error)
    }
}
 
/** PrevAction Dispatch function */
export const MovePrevQuestion = () => async (dispatch) => {
    try {
        dispatch(Action.movePrevAction()); /** decrease trace by 1 */
    } catch (error) {
        console.log(error)
    }
}


Javascript




import { postServerData } from '../helper/helper'
import * as Action from '../redux/result_reducer'
 
export const PushAnswer = (result) => async (dispatch) => {
    try {
        await dispatch(Action.pushResultAction(result))
    } catch (error) {
        console.log(error)
    }
}
export const updateResult = (index) => async (dispatch) => {
    try {
        dispatch(Action.updateResultAction(index));
    } catch (error) {
        console.log(error)
    }
}
 
/** insert user data */
export const usePublishResult = (resultData) => {
    const { result, username } = resultData;
    (async () => {
        try {
            if (result !== [] && !username)
                throw new Error("Couldn't get Result");
            await postServerData(`http://localhost:${process.env.PORT}/api/result`,
                resultData, data => data)
        } catch (error) {
            console.log(error)
        }
    })();
}


Javascript




// question_reducer.js
 
import { createSlice } from "@reduxjs/toolkit";
 
/** create reducer */
export const questionReducer = createSlice({
    name: 'questions',
    initialState: {
        queue: [],
        answers: [],
        trace: 0
    },
    reducers: {
        startExamAction: (state, action) => {
            let { question, answers } = action.payload
            return {
                ...state,
                queue: question,
                answers
            }
        },
        moveNextAction: (state) => {
            return {
                ...state,
                trace: state.trace + 1
            }
        },
        movePrevAction: (state) => {
            return {
                ...state,
                trace: state.trace - 1
            }
        },
        resetAllAction: () => {
            return {
                queue: [],
                answers: [],
                trace: 0
            }
        }
    }
})
 
export const { startExamAction,
    moveNextAction,
    movePrevAction,
    resetAllAction } = questionReducer.actions;
 
export default questionReducer.reducer;


Javascript




// result_reducer.js
 
import { createSlice } from "@reduxjs/toolkit"
 
export const resultReducer = createSlice({
    name: 'result',
    initialState: {
        userId: null,
        result: []
    },
    reducers: {
        setUserId: (state, action) => {
            state.userId = action.payload
        },
        pushResultAction: (state, action) => {
            state.result.push(action.payload)
        },
        updateResultAction: (state, action) => {
            const { trace, checked } = action.payload;
            state.result.fill(checked, trace, trace + 1)
        },
        resetResultAction: () => {
            return {
                userId: null,
                result: []
            }
        }
    }
})
 
export const { setUserId,
    pushResultAction,
    resetResultAction,
    updateResultAction } = resultReducer.actions;
 
export default resultReducer.reducer;


Javascript




// store.js
 
import {
    combineReducers,
    configureStore
} from '@reduxjs/toolkit';
 
/** call reducers */
import questionReducer from './question_reducer';
import resultReducer from './result_reducer';
 
const rootReducer = combineReducers({
    questions: questionReducer,
    result: resultReducer
})
 
/** create store with reducer */
export default configureStore({ reducer: rootReducer });


Javascript




import './App.css';
 
import {
    createBrowserRouter,
    RouterProvider
} from 'react-router-dom'
 
/** import components */
import Main from './Main.js';
import Quiz from './Quiz.js';
import Result from './Result.js';
import { CheckUserExist } from '../src/helper/';
 
/** react routes */
const router = createBrowserRouter([
    {
        path: '/',
        element: <Main></Main>
    },
    {
        path: '/quiz',
        element: <CheckUserExist><Quiz /></CheckUserExist>
    },
    {
        path: '/result',
        element: <CheckUserExist><Result /></CheckUserExist>
    },
])
 
function App() {
    return (
        <>
            <RouterProvider router={router} />
        </>
    );
}
 
export default App;


Steps to run the App:

  • To run Backend:
node server.js
  • To run Frontend:
npm start

Output:

Quiz_App_MERN_Output

Output



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads