20. Mark notifications as read

In the previous tutorial, when someone sends a group invite, we are adding an element in the user’s notifications array and setting its isRead to false. Now we need to mark notifications as read when the user opens the notification page.

Create a notification bell icon

Open AppHeader.vue and show a notification bell after the logout button.

<li class="nav-item" v-if="login">
    <router-link class="nav-link" to="/notifications">
        <i class="fa fa-bell"></i>
        <span class="badge" v-if="unreadNotifications > 0" v-text="unreadNotifications"></span>
    </router-link>
</li>

Then we need to create a computed property for un-read notifications. It will be an integer value.

computed: {
    unreadNotifications() {
        return store.getters.getUnreadNotifications
    }
},

Then we need to create a getter in our Vuex store that will return this value. In your vuex/store.js first, define a variable:

export default createStore({
    state() {
        return {
            ...
            unreadNotifications: 0,
        }
    },
    ...
})

Then create a getter for this value.

getters: {
    getNotifications (state) {
        return state.notifications
    },
    ...
}

After that, we need to set its value. To do that, first, we need to get it from the API. So in your api/server.js in the /getUser API, you need to make the following changes:

app.post("/getUser", auth, async function (request, result) {
    const user = request.user;

    // get number of unread notifications
    let unreadNotifications = 0;
    if (user.notifications) {
        for (let a = 0; a < user.notifications.length; a++) {
            if (!user.notifications[a].isRead) {
                unreadNotifications++;
            }
        }
    }

    result.json({
        status: "success",
        message: "Data has been fetched.",
        user: user,

        // send to client
        unreadNotifications: unreadNotifications
    });
});

Since this API is being called in AppHeader. So you need to open AppHeader.vue and where this API is called and the response status is a success, write the following line:

store.commit("setUnreadNotifications", response.data.unreadNotifications)

This requires a setUnreadNotifications method in the Vuex store, so we are going to create one. Open your vuex/store.js and create the following mutator:

mutations: {

    setUnreadNotifications (state, unreadNotifications) {
        state.unreadNotifications = unreadNotifications
    },

    ...
}

Right now, you will be able to see the bell icon on the top navbar and a number of unread notifications if there are any. When this bell icon is clicked, you will be moved to a new page.

Create notifications component

We need to create a route for this page and a component. So open your main.js and create its route and component.

import NotificationsComponent from "./components/NotificationsComponent.vue"

const routes = [
    ...

    { path: "/notifications", component: NotificationsComponent },
];

After that, create a new file named NotificationsComponent.vue in your components folder. Write the following code in this component:

<template>
    <div class="container">
        <!-- heading -->
        <div class="row">
            <div class="col-md-12">
                <h1 class="text-center text-white">Notifications</h1>
            </div>
        </div>
    </div>
</template>

<script>

    import axios from "axios"
    import swal from "sweetalert2"
    import store from "../vuex/store"

    export default {

        methods: {
            // method to mark all notifications as read
            markAsRead: async function () {
                const response = await axios.post(
                    this.$apiURL + "/markNotificationsAsRead",
                    null,
                    {
                        headers: this.$headers
                    }
                )

                if (response.data.status == "success") {
                    // set the unread notifications to zero
                    store.commit("setUnreadNotifications", 0)
                }
            },
        },

        // on page loaded, mark all notifications as read
        mounted: function () {
            this.markAsRead()
        },
    }
</script>

Then we need to create an API that will set the isRead to true on all notifications of the logged-in user in Mongo DB.

Create an API to mark notifications as read

Open your server.js and create an API in it:

app.post("/markNotificationsAsRead", auth, async function (request, result) {
    // get authenticated user
    const user = request.user;

    // mark isRead to true in each element of notifications array 
    await db.collection("users").findOneAndUpdate({
        _id: user._id
    }, {
        $set: {
            "notifications.$[].isRead": true
        }
    });

    result.json({
        status: "success",
        message: "Notification has been marked as read."
    });
});

Right now, if the user has any notifications, then he will see the number of notifications in the top bar. As soon as he moved to the notifications page, you will see that after a few seconds the number of notifications in the top bar is removed. This means that they have been updated in the local array. You can also refresh your Mongo DB compass and you will see that all notifications isRead value has been set to true.

That’s how you can mark notifications as read when user accessed the notifications page.





Please disable your adblocker or whitelist this site!