19. Invite member
The group is all about people. That’s what it means. In the previous tutorial, we displayed all groups in a tabular form but there was only one member in that group, that is the admin. So in this tutorial, we are going to invite member to join the group. To add anyone to the group, we must first get their permission. So we are going to send an invitation to that person to join the group. He can either accept or reject that request.
Get the email of the user to invite
First, in your GroupsComponent.vue inside the for
loop, in the last <td>
where we have created buttons to edit and delete the group. We are going to add another button:
<!-- a button to invite member -->
<a v-bind:data-id="group._id" v-on:click.prevent="inviteMember" class="btn btn-success" style="margin-left: 10px;">Invite member</a>
This will call a method when clicked. So we need to create a method in our methods object.
// method to invite member
inviteMember: function () {
// get vue instance
const self = this
// get group _id from anchor tag
const _id = event.target.getAttribute("data-id")
// show pop-up and ask for user email to send invitation to join group
swal.fire({
title: 'Enter user email',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Invite User',
showLoaderOnConfirm: true,
preConfirm: async function (email) {
// called when email address is entered
// attach group ID and user email to the form data object
const formData = new FormData()
formData.append("_id", _id)
formData.append("email", email)
// using fetch API send the AJAX request
return fetch(self.$apiURL + "/groups/inviteMember", {
method: 'POST',
body: formData,
headers: {
'Authorization': 'Bearer ' + localStorage.getItem(self.$accessTokenKey)
}
})
.then(function (response) {
// called when the response is received from server
// check if the status code is not 200
if (!response.ok) {
throw new Error(response.statusText)
}
// check if there isn't any error from server
return response.json().then(function (value) {
if (value.status == "error") {
throw new Error(value.message)
}
// return the success response
return value
})
})
.catch(function (error) {
// show error inside sweetalert
swal.showValidationMessage(`Request failed: ${error}`)
})
},
// disable clicking outside
allowOutsideClick: function () {
!swal.isLoading()
}
}).then(function (result) {
// show success response in sweetalert dialog
if (result.isConfirmed) {
swal.fire("Invite member", result.value.message, "success")
}
})
},
We are using a Sweetalert pop-up and it uses promises. To learn more about promises, you can follow this link.
Now we need to create an API that will handle this request. Open your api/modules/groups.js and first include the Mongo DB ObjectId in it, because we will be using it to generate a new unique ID for the member and for setting notification ID.
Create an API to invite member
// each Mongo document's unique ID
var ObjectId = require("mongodb").ObjectId;
After that, we need to create an API that will send the invitation to the user after passing some validations.
router.post("/inviteMember", auth, async function (request, result) {
// get logged-in users
const user = request.user;
// get unique ID of group
const _id = request.fields._id;
// get email of user
const email = request.fields.email;
// check if group exists
const group = await db.collection("groups").findOne({
"_id": ObjectId(_id)
});
if (group == null) {
result.json({
status: "error",
message: "Group does not exists."
});
return;
}
// check if user exists
const member = await db.collection("users").findOne({
"email": email
});
if (member == null) {
result.json({
status: "error",
message: "User does not exists."
});
return;
}
// check if user is already a member or admin of group
let isAlreadyMember = false;
for (let a = 0; a < group.members.length; a++) {
if (group.members[a].user.email == email) {
isAlreadyMember = true;
break;
}
}
if (group.createdBy.email == email || isAlreadyMember) {
result.json({
status: "error",
message: "User is already a member of this group."
});
return;
}
// insert in group's members array
await db.collection("groups").findOneAndUpdate({
_id: group._id
}, {
$push: {
members: {
_id: ObjectId(),
status: "pending", // pending, accepted
sentBy: {
_id: user._id,
name: user.name,
email: user.email
},
user: {
_id: member._id,
name: member.name,
email: member.email
},
createdAt: new Date().getTime()
}
}
});
// send notification to the user
await db.collection("users").findOneAndUpdate({
_id: member._id
}, {
$push: {
notifications: {
_id: ObjectId(),
type: "group_invite",
group: {
_id: group._id,
name: group.name
},
isRead: false,
sentBy: {
_id: user._id,
name: user.name,
email: user.email
},
createdAt: new Date().getTime()
}
}
});
// send the response back to client
result.json({
status: "success",
message: "Invitation has been sent."
});
});
Test the app now. First, try entering the email address of the user that does not exist. You will get the following error:

Then try entering the email address of a user who is either an admin or already a member of the group. In that case, you will get the following error:

And finally try to enter the email address of a user who is neither an admin nor a member of this group, but has a registered account. Then you will see a success message.

Check the Mongo DB groups collection and you will see that a new element has been inserted in the members array. Also, if you check the users collection, you will see that a new element has been added to the notifications array of that user to whom you have sent an invite.