18. Show groups

Now we need to show all groups in a tabular form. First, in our web/src/vuex/store.js, we need to initialize an array for groups.

export default createStore({
    state() {
        return {
            ...

            // initialize groups array
            groups: []
        }
    },

    ...
})

Then, we need to create a new method in the mutations object that will set the value to this group’s array.

mutations: {
    // set the groups value
    setGroups (state, newGroups) {
        state.groups = newGroups
    },

    ...
}

After that, we need to create a method in the getters object to get this array.

getters: {
    // get the state groups
    getGroups (state) {
        return state.groups
    },

    ...
}

So the getter and mutators are set, now we need to call an API from our GroupsComponent.vue. The following code will go in the groups component <script> tag:

// axios for calling AJAX
import axios from "axios"

// to show pop-up alerts
import swal from "sweetalert2"

// vuex store is used to use the variables throughout the application
import store from "../vuex/store"

export default {
    data() {
        return {
            isDeleting: false,

            // logged-in user object
            user: null
        }
    },

    // using computed property, we can update value from anywhere in the app
    computed: {
        groups() {
            return store.getters.getGroups
        }
    },

    methods: {
        // a method to fetch all groups from API
        getData: async function (request, result) {
            const response = await axios.post(
                this.$apiURL + "/groups/fetch",
                null,
                {
                    headers: this.$headers
                }
            )

            if (response.data.status == "success") {
                // set logged-in user object
                this.user = response.data.user

                // call the setGroups from vuex store
                store.commit("setGroups", response.data.groups)
            } else {
                swal.fire("Error", response.data.message, "error");
            }
        }
    },

    // get the data when this component is mounted
    mounted: function () {
        this.getData()
    }
}

Now we need to create an API that will handle this request. So create a POST method request in your api/modules/groups.js module.

// POST API to fetch groups
router.post("/fetch", auth, async function (request, result) {
    // get logged-in users
    const user = request.user;

    // get groups of which I am an admin or a member
    const groups = await db.collection("groups").find({
        $or: [{
            "createdBy._id": user._id
        }, {
            "members.user._id": user._id
        }]
    })
        .sort({
            "createdAt": -1
        })
        .toArray();

    // return the groups and logged-in user object
    result.json({
        status: "success",
        message: "Groups has been fetched.",
        groups: groups,
        user: user
    });
});

If you do console.log(response.data.groups) on your client-side, you will see all groups which are created by you or whom you are a member of. So all the required data has been fetched, and now we can show it in our GroupsComponent.

<!-- show all groups -->
<div class="row">
	<div class="col-md-12">
		<table class="table table-hover">
			<!-- heading of table -->
			<thead>
				<tr>
					<th>Name</th>
					<th>Created by</th>
					<th>Actions</th>
				</tr>
			</thead>

			<tbody>
				<!-- loop through all groups -->
				<tr v-for="group in groups" v-bind:key="group._id">
					<td>
						<!-- show group name -->
						<span v-text="group.name"></span>
					</td>

					<!-- the admin of group -->
					<td v-text="group.createdBy.name"></td>

					<td style="display: flex;">

						<!-- buttons to edit and delete the group, only for group admin -->
						<template v-if="user != null && group.createdBy._id == user._id">
							<!-- edit the group -->
							<router-link v-bind:to="'/groups/edit/' + group._id" class="btn btn-primary" style="margin-right: 10px;">Edit</router-link>

							<!-- delete the group -->
							<form v-on:submit.prevent="deleteGroup">
								<input type="hidden" name="_id" v-bind:value="group._id" required />
								<input type="submit" v-bind:value="isDeleting ? 'Deleting...' : 'Delete'" v-bind:isDeleting="disabled" class="btn btn-danger" />
							</form>
						</template>
					</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>

If you test the app now, you will be able to see all your groups. If everything works fine, you will see all your groups in a tabular form similar to the screenshot below.

show all groups
show all groups

Try logging in with a different account in a different browser and you will see that groups are only being displayed to the person who is an admin or a member of the group.

That’s how you can show groups that we created in the previous step. For more details on how vuex works, you can learn from their official documentation.