Express.js integration

How to use Vue with Express.js - free starter

This guide will provide you with a free template for a Express.js application, with MongoDB database and Vue + Bootstrap 5 front-end.

Lets see how to integrate Express.js application with MDB 5 in our layout, components, and utilities.


Prerequisites

Before starting the project make sure to install the following utilities:

  • Node LTS (14.x.x or higher recommended)
  • Code editor. We recommend VSCode

Creating a new Express.js project

For our example, we will create a new Express.js application from mdb starter. Navigate to your project directory, i.e. mdb-vue-express-app and follow the steps below.

Step 1

Creating MongoDB database.

In order to create a new database you need to run the following command:

        
            
        mdb database init -db mongodb
    
        
    
  • Create a new user
  • Provide username, password, database name and description.

Note: the password must contain at least one uppercase letter, one lowercase letter, one number, one special symbol and have minimum length of 8.

Important Do not close your terminal window until you save your credentials somewhere. This is the only time we will show you your database password. If you won't save it you'll loose it.

Step 2

Creating Node.js API with Express and Mongoose.

In case you don't know, Mongoose is a MongoDB object modeling tool. It helps managing MongoDB access and models. You can initialize a MDB GO starter that already has configured Mongoose. Simply run the following command:

        
            
      mdb backend init
    
        
    

and choose Express.js + MongoDB API starter from the list that shows up.

After initialization just go to the newly created project directory and open the .env file. After that edit the DB_CONNECTION_STRING value. You should paste the connection string that's been shown to you in the previous step.

Step 3

We have to add one more thing to the project. Let's install CORS and add them to index.js

        
            
      npm install cors 
    
        
    

Add cors package after require("./app/config") and use it after app.use(bodyParser.json());

        
            
      ...
      const cors = require("cors");
      ...
      app.use(cors());
    
        
    

Step 4

The starter project is ready to use. You don't have to change anything to run the example app for the sake of this tutorial. Simply publish it using the following command:

        
            
    mdb publish -p node12
    
        
    

Note Since we need to install dependencies and run your app, it may take a few moments until it will be available under the provided URL.

When you open the app URL you will see the default view on the / endpoint but when you'll visit /tasks you will see an empty array indicating that the tasks collection has been created and is empty. There are also other endpoints defined like this:

  • GET /tasks/:id
  • POST /tasks
  • PUT /tasks/:id
  • DELETE /tasks/:id

Creating MDB Vue application

If our Express.js is working correctly we should start creating a new Vite application. If you have encountered any problems, you should go back and try each step again.

Note: Don't forget to go back to your root folder before next step. Folders node-free-express-mongoose and mdb5-free-vue should be in the same directory.

Step 1

Create a new vite project with our MDB starter. Run the command below and select MDB5 Free Vue starter.

        
            
            mdb init
      
        
    

Your folder structure should look like this

        
          mdb-vue-express-app/
          ├── mdb5-free-vue
          └── node-free-express-mongoose
        
      

Step 2

Let's make some changes to the created vue app. First we need to install axios inside our mdb5-free-vue directory.

        
            
            npm install axios
      
        
    

Remove style.css file (don't forget to delete it from main.ts file) and remove HelloWorld file from components directory.

Step 3

Let's create a .env file inside a mdb5-free-vue directory. We have to add VITE_ before the name of your variable, because it's the only way to expose them to Vite-processed code. Don't forget to change URL to the one you created earlier.

        
            
            VITE_API = "LINK_TO_YOUR_BACKEND_APP"
      
        
    

Step 4

Add new content to Home.vue file inside the views directory.

Since our starter database contains some sample models and routes, let's use them. We will create an application that will show a list of tasks. We also intend to create a functonality for adding new tasks, changing their content and removing them.

We have already prepared the code for you, so go ahead and copy and paste it into App.vue.

Ok, so what's actually going on there. We use MDB components, MDBBtn, MDBModal, MDBListGroup, MDBInputs and few other. The modal will be responsible to show inputs that will allow you to add, edit and send tasks to the database. The Manage tasks button, gives possibilty to modify or remove tasks. At the end, the list group will display our data.

        
            
      <template>
        <MDBContainer class="mt-5">
          <MDBRow class="pt-5">
            <MDBCol class="text-center">
              <MDBBtn color="primary" @click="taskModal = true">Add task</MDBBtn>
            </MDBCol>
          </MDBRow>
          <MDBRow class="mt-3 p-5" style="min-height: 40vh">
            <MDBCol class="d-flex justify-content-center align-items-center">
              <div v-if="taskList.length === 0">
                Nothing to display. Add a few tasks.
              </div>
              <MDBListGroup v-else class="list-group-light" style="min-width: 22rem">
                <MDBListGroupItem
                  class="d-flex justify-content-between align-items-center gap-5"
                  v-for="task in taskList"
                  :key="task._id"
                >
                  <div>
                    <div class="fw-bold">
                      {{ task.name }}
                    </div>
                    <div class="text-muted">{{ task.desc }}</div>
                  </div>
                  <div>
                    <MDBIcon
                      class="text-primary me-3"
                      title="edit"
                      icon="pen"
                      style="cursor: pointer"
                      @click="() => editModal(task)"
                    />
                    <MDBIcon
                      class="text-danger"
                      title="delete"
                      icon="trash"
                      style="cursor: pointer"
                      @click="() => deleteTask(task._id)"
                    />
                  </div>
                </MDBListGroupItem>
              </MDBListGroup>
            </MDBCol>
          </MDBRow>
        </MDBContainer>
        <MDBModal
          id="addNewTaskModal"
          tabindex="-1"
          labelledby="addNewTaskModalLabel"
          v-model="taskModal"
        >
          <MDBModalHeader>
            <MDBModalTitle id="exampleModalLabel">{{
              isEdited.edited ? "Edit task" : "Add task"
            }}</MDBModalTitle>
          </MDBModalHeader>
          <MDBModalBody>
            <form>
              <div class="my-4">
                <MDBInput
                  label="Name"
                  type="text"
                  v-model="newTaskName"
                  counter
                  :maxlength="60"
                />
              </div>
              <div class="my-4">
                <MDBInput
                  label="Description"
                  type="text"
                  v-model="newTaskDesc"
                  counter
                  :maxlength="255"
                />
              </div>
            </form>
          </MDBModalBody>
          <MDBModalFooter>
            <MDBBtn
              color="secondary"
              @click="
                {
                  resetInputs();
                  taskModal = false;
                }
              "
              >Close</MDBBtn
            >
            <MDBBtn
              color="primary"
              @click="handleSaveChanges"
              :disabled="!canSendData"
              >{{ isEdited.edited ? "Save changes" : "Add task" }}</MDBBtn
            >
          </MDBModalFooter>
        </MDBModal>
      </template>
      
        
    
        
            
      <script setup lang="ts">
        import { ref, onMounted, computed } from "vue";
        import {
          MDBContainer,
          MDBRow,
          MDBCol,
          MDBListGroup,
          MDBListGroupItem,
          MDBBtn,
          MDBModal,
          MDBModalTitle,
          MDBModalHeader,
          MDBModalBody,
          MDBModalFooter,
          MDBInput,
          MDBIcon,
        } from "mdb-vue-ui-kit";
        import axios from "axios";
        
        interface SingleTask {
          _id: number;
          name: string;
          desc: string;
        }
        
        const taskList = ref<SingleTask[]>([]);
        const taskModal = ref(false);
        const newTaskName = ref("");
        const newTaskDesc = ref("");
        const isEdited = ref({ edited: false, value: -1 });
        const API_URL = ref("");
        
        const canSendData = computed(() => {
          if (newTaskName.value.trim() === "" || newTaskDesc.value.trim() === "") {
            return false;
          }
          return true;
        });
        
        const resetInputs = () => {
          newTaskName.value = "";
          newTaskDesc.value = "";
          isEdited.value = { edited: false, value: -1 };
        };
        
        const handleSaveChanges = async () => {
          if (!canSendData.value) {
            return;
          }
        
          isEdited.value.edited
            ? updateTask(isEdited.value.value, newTaskName.value, newTaskDesc.value)
            : createTask(newTaskName.value, newTaskDesc.value);
          resetInputs();
          taskModal.value = false;
        };
        
        const editModal = (task: SingleTask) => {
          newTaskName.value = task.name;
          newTaskDesc.value = task.desc;
          isEdited.value = { edited: true, value: task._id };
        
          taskModal.value = true;
        };
        
        const getTaskList = () => {
          axios.get(`${API_URL.value}tasks`).then((res) => (taskList.value = res.data));
        };
        
        const createTask = (name: string, desc: string) => {
          const data = { name, desc };
          axios.post(`${API_URL.value}tasks`, data).then(() => {
            getTaskList();
          });
        };
        
        const deleteTask = (id: number) => {
          axios.delete(`${API_URL.value}tasks/${id}`).then(() => {
            getTaskList();
          });
        };
        
        const updateTask = (id: number, name: string, desc: string) => {
          const data = { name, desc };
          axios.put(`${API_URL.value}tasks/${id}`, data).then(() => {
            getTaskList();
          });
        };
        
        onMounted(() => {
          API_URL.value = import.meta.env.VITE_API;
          getTaskList();
        });
        </script>
      
        
    

If you haven't done it already, run npm start in your terminal. The app should be fully functional and should work correctly with backend.

Step 5

Now you can publish your project on MDB GO

        
            
          mdb publish
      
        
    

Optimization

If you want to further optimize your application please visit:


Backend features

Express.js:

This example was created with use of Express.js. By using our Express.js + MongoDB API starter we got a ready environment to start a new project.


Frontend features

MDB UI KIT:

To create the project we used our ui kit, with which we can build basic views very quickly.

Views and Layouts:

In this project we used the Home.vue file, created by the Vite tool in which we placed our vue code. We have successfully integrated the Express.js + MongoDB API starter with the MDB Vue package and can send get, post, put and delete requests to the database.