17. Create group

Groups are used by teams to send the same message to multiple users. You can create multiple groups and add as many members as you want. In this tutorial, we will create a feature that will allow the users to create group. Following features we will do in this module:

  1. Create group
  2. Show all groups
  3. Send an invitation to join the group
    • Other members can accept the request
  1. Show all members of a group
  2. Delete any member
  3. Send a message with an attachment
  4. Leave group
  5. Change admin of the group

So the first thing we need to do is to create a group.

Create group

To create a group, first, open your AppHeader.vue and create the following link in the navbar.

<!-- link to show all groups, only to logged-in users -->
<li class="nav-item" v-if="login">
    <router-link class="nav-link" to="/groups">Groups</router-link>
</li>

Then we need to create its route in main.js:

// component to show all groups
import GroupsComponent from "./components/GroupsComponent.vue"

const routes = [
    ...

    // route to show all groups
    { path: "/groups", component: GroupsComponent },
];

Then create a file named GroupsComponent.vue in your components folder. Following will be the code of this file:

<template>
    <div class="container">
        <div class="row">
            <div class="offset-md-10 col-md-2">
            	<!-- link to create group -->
                <router-link class="btn btn-primary" to="/groups/add">Add group</router-link>
            </div>
        </div>
    </div>
</template>

<script>

	export default {
		//
	}
</script>

Right now, you will only see a button that says “Add group”. Then we need to create its route in the main.js file the same way as we did for groups.

// component to create new group
import AddGroupComponent from "./components/AddGroupComponent.vue"

const routes = [
    ...

    // route to create new group
    { path: "/groups/add", component: AddGroupComponent },
];

Then again, we need to create a file named AddGroupComponent.vue in our components folder. Following will be the code of this file:

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

		<div class="row">
			<div class="offset-md-3 col-md-6">

				<!-- form to create new group -->
				<form method="POST" v-on:submit.prevent="addGroup">

					<!-- input field for name of group -->
					<div class="form-group">
						<label class="text-white">Name</label>
						<input type="text" name="name" class="form-control" required />
					</div>

					<!-- input field for selecting the picture of group (optional) -->
					<div class="form-group" style="margin-top: 20px; margin-bottom: 30px;">
						<label class="text-white">Picture</label>
						<input type="file" name="picture" accept="image/*" class="form-control" />
					</div>

					<!-- submit button -->
					<div class="d-grid gap-2">
						<input type="submit" class="btn btn-primary btn-block" v-bind:value="isLoading ? 'Creating...' : 'Create group'" v-bind:disabled="isLoading" />
					</div>
				</form>
			</div>
		</div>
	</div>
</template>

<script>
	// axios for calling AJAX
	import axios from "axios"

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

	export default {
		// all the variables we will be using in this component
		data() {
			return {
				"isLoading": false
			}
		},

		methods: {
			// method which called when the form submits
			addGroup: async function () {
				// get the form
				const form = event.target

				// create form data object
				const formData = new FormData(form)

				// show loading message
				this.isLoading = true

				// call an AJAX
				const response = await axios.post(
					this.$apiURL + "/groups/add",
					formData,
					{
						headers: this.$headers
					}
				)
				
				// hide the loading message
				this.isLoading = false

				// show response from server
				swal.fire("Add group", response.data.message, response.data.status)

				// reset the form if the group is successfully created
				if (response.data.status == "success") {
					form.reset()
				}
			}
		},
	}
</script>

At this point, your front end will look like this when you access the add group route.

create group
create group

Now we need to create an API that will handle this request. Since there will be a lot of functions in the group feature, so we will create a separate module for this, the same way we did for chat and contacts. Create a new file named groups.js inside your api/modules folder. Following will be the code of this module:

// include auth module for getting logged-in user
const auth = require("./auth");

// fs module to save group images
const fileSystem = require("fs");

module.exports = {
    // initialize the module
    init: function (app, express) {

        // create a new router object from express
        const router = express.Router();

        // create a POST method
        router.post("/add", auth, async function (request, result) {
            // get logged-in user
            const user = request.user;

            // get name of group
            const name = request.fields.name;

            // get picture of group
            const picture = request.files.picture;

            // get current time
            const createdAt = new Date().getTime();

            // create group object for saving in Mongo DB
            const object = {
                name: name,
                createdBy: {
                    _id: user._id,
                    name: user.name,
                    email: user.email
                },
                // array that will store list of all members
                members: [],
                createdAt: createdAt
            };

            // check if file is selected and file type is image
            if (picture != null && picture.size > 0 && (picture.type == "image/png" || picture.type == "image/jpeg" || picture.type == "image/HEIC")) {

                // set the unique name of file
                const dateObj = new Date();
                const datetimeStr = dateObj.getFullYear() + "-" + (dateObj.getMonth() + 1) + "-" + dateObj.getDate() + " " + dateObj.getHours() + ":" + dateObj.getMinutes() + ":" + dateObj.getSeconds();
                const fileName = "ChatStation-" + name + "-" + datetimeStr + "-" + picture.name;

                // set the path of file, you might need to create a new folder "groups" in uploads folder
                const filePath = "uploads/groups/" + fileName;

                // attach this picture to the groups object
                object.picture = {
                    size: picture.size,
                    path: filePath,
                    name: fileName,
                    displayName: picture.name,
                    type: picture.type
                };

                // read the content of image
                fileSystem.readFile(picture.path, function (error, data) {
                    if (error) {
                        console.error(error);
                    }

                    // save the file
                    fileSystem.writeFile(filePath, data, function (error) {
                        if (error) {
                            console.error(error);
                        }
                    });

                    // delete the temporary file path
                    fileSystem.unlink(picture.path, function (error) {
                        if (error) {
                            console.error(error);
                        }
                    });
                });
            }

            // save the group in Mongo DB
            const group = await db.collection("groups").insertOne(object);

            // attach the newly inserted ID to the group's object
            object._id = group.insertedId;

            // send the response back to client along with new group object
            result.json({
                status: "success",
                message: "Group has been created.",
                group: object
            });
        });

        // handle all requests by this router, that starts with "/groups"
        app.use("/groups", router);
    }
};

Comments have been added with each line for the explanation. But if you still don’t understand any line, feel free to contact us.

The final thing you need to do is to include this module in your api/server.js file:

const groups = require("./modules/groups");

And after the database is successfully connected, you need to initialize this module and pass the app, and express object as the parameter.

groups.init(app, express);

Now you are free to test the app. Fill out the form and hit submit, you will see a pop-up alert saying that the group has been created. You will also see the selected picture saved in the uploads/groups folder. Since group picture is optional, so you can also create a group without selecting any picture.

In the next tutorial, we will display all these groups in a tabular form.





Please disable your adblocker or whitelist this site!