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:
- Create group
- Show all groups
- Send an invitation to join the group
- Other members can accept the request
- Show all members of a group
- Delete any member
- Send a message with an attachment
- Leave group
- 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.

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.