MDB Vue with Express.js

web
mobile

Topic: MDB Vue with Express.js
Published 26.09.2019 Updated 26.09.2019

Introduction

Express.js is fast, unopinionated, minimalist web framework for Node.js. It is designed for building web applications and APIs. In this tutorial, we'll use Vue for the front-end and Express with mongoDB for the back-end of a full-stack web application.



Prerequisites

Make sure to install the following items globally:

Node.jshttps://nodejs.org/en/

Vue CLI: https://cli.vuejs.org/guide/installation.html

MongoDB: https://www.mongodb.com/download-center/community



Quick start

Working template is ready to be cloned from the GitHub repo:

git clone https://github.com/smolenski-mikolaj/MDB-Vue-with-ExpressJS.git

After cloning let's install it:

cd ./MDB-Vue-with-ExpressJS
npm install

Now, it's time to run backend and frontend separately in two terminals

First:

npm start

Second:

cd ./mdb-front
npm start


Great! You should see now working App:


Express configuration

Main backend file is server.js in the root of the project. At first we have to connect to the database using mongoose:

const express = require('express'),
  bodyParser = require('body-parser'),
  cors = require('cors'),
  mongoose = require('mongoose'),
  Todo = require('./models/todo'),
  port = process.env.PORT || 4000;

mongoose.connect('mongodb://localhost:27017/vuenodedb', { useNewUrlParser: true }).then(
  () => {
    console.log('Database connection is successful')
},
  err => { console.log('Error when connecting to the database' + err) }
);


That will establish connection with vuenodedb where we will store all data.

After establishing connection there is a need to create the express server:

mongoose.connect('mongodb://localhost:27017/vuenodedb', { useNewUrlParser: true }).then(
  () => {
    console.log('Database connection is successful')

    const app = express();
    app.use(express.static('public'));
    app.use(bodyParser.json());
    app.use(cors());


    app.listen(port, () => {
      console.log('Listening on port ' + port);
    });
},
  err => { console.log('Error when connecting to the database' + err) }
);


Finally, there are three endpoints created for getting, creating and deleting todos from the database:

    app.post('/api/todos/create', (reqres=> {
      const todo = new Todo(req.body);
      todo.save(err => {
        if (errres.status(500).send('Error when saving to database');
        else res.json({ status: 200message: 'Todo successfully created' });
      });
    });
    
    app.get('/api/todos', (reqres=> {
      Todo.find((errtodos=> {
        if (errres.status(500).send('Error when getting data from database');
        else res.json({ status: 200message: 'Todos successfully received'data: todos });
      });
    });

    app.delete('/api/todos/delete/:id', (reqres=> {
      Todo.findByIdAndRemove({ _id: req.params.id }, { useFindAndModify: false }, err => {
        if (errres.status(500).send('Error when deleting from database');
        else res.json({ status: 200message: 'Todo successfully removed' });
      });
    });


In the server.js we also import models/todo.js file where the ToDo schema is saved:

const mongoose = require('mongoose');

const TodoSchema = mongoose.Schema({
  name: String
}, {
  timestamps: true
});

module.exports = mongoose.model('Todo'TodoSchema);


Note! While creating a new Todo in the production mode you should always prepare some validation rules! In this example everything the user write in the input field will be sent do database which can crash it. In addition, while the app is growing it's a good practise to move db connection and endpoints to the separate files.



Vue CLI configuration

Frontend logic is located in the ./mdb-front dir and the app template is stored in App.vue inside ./src dir. Let's analize it!

<template>
  <div id="app">
    <mdb-container>
      <div class="text-center mb-4">
        <h1 class="font-weight-bold mb-4">MDB Vue Todo Demo Apph1>
        <img src="./assets/logo-mdb-vue-small.png" width="100px" height="auto"> + <img src="./assets/express.png" width="100px" height="auto"> + <img src="./assets/mongo.png" width="100px" height="auto"><br>
      div>
      <mdb-row>
        <mdb-col md="6">
          <CreateToDo @createTodo="createTodo/>
        mdb-col>
        <mdb-col md="6">
          <ListToDo :todos="todos" @deleteTodo="deleteTodo/>
        mdb-col>
      mdb-row>
    mdb-container>
  div>
template>


Above we can see the main template. All events happens inside two components: CreateToDo and ListToDo. The first one is basically an input which gives an ability to create the new Todo. Just after submitting it emits the createTodo event. 

ListToDo component stores all todos (which are passed using props) and displays them in the table. It also emits an event - deleteTodo. This event is used for removing a specific todo from the database.

To post or get from the database we'll have to define APIService:

import axios from 'axios';
const API_URL = 'http://localhost:4000';

export class APIService {
  getTodos() {
    this.url = `${API_URL}/api/todos/`;
    return axios.get(this.url).then(response => response.data);
  }
  deleteTodo(todo) {
    this.url = `${API_URL}/api/todos/delete/${todo._id}`;
    return axios.delete(this.url);
  }
  createTodo(todo) {
    this.url = `${API_URL}/api/todos/create/`;
    return axios.post(this.urltodo);
  }
}


APIService is imported in the App.vue and then used for the backend-frontend communication:

<script>
import CreateToDo from './components/CreateTodo'
import ListToDo from './components/ListTodo'

import { APIService } from './APIService'
const API_URL = 'http://localhost:4000'
const apiService = new APIService()

import { mdbContainermdbRowmdbCol } from 'mdbvue'

export default {
  name: 'App',
  components: {
    CreateToDo,
    ListToDo,
    mdbContainer,
    mdbRow,
    mdbCol
  },
  data() {
    return {
      todos: []
    }
  },
  methods: {
    getTodos() {
      apiService.getTodos().then(response => {
        console.log(response.message)
        this.todos = response.data
      })
    },
    createTodo(todo) {
      apiService.createTodo(todo).then(
        request => {
          console.log(request.data.message)
          this.getTodos()
        }
      );
    },
    deleteTodo(todo) {
      apiService.deleteTodo(todo).then(response => {
        if (response.status === 200) {
          console.log(response.data.message)
          this.getTodos()
        }
      })
    }
  },
  mounted() {
    this.getTodos()
  }
}
script>

<style>
#app {
  margin-top100px;
}
style>


As you can see - we use three apiService methods for the communication with the mongo database.



Summary

In this tutorial, we've created a TODO application with Node.js and Vue which consumes a REST API created with Express.

Write
Please insert min. 20 characters.