vuejs 2 crud with nodjs


for our crud application, we will create two side such as frontend and backend. we use vuejs 2 for frontend so make sure you install latest package for vuejs 2 and nodejs for backend in our project here.let go to step 1

Part 1 : for backend

step 1 : create new folder give the name as you like and then create file package.json with content below : 

{
  "name": "vueserver",
  "version": "1.0.0",
  "description": "server side for vuecrud",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "chea sotheara",
  "license": "MIT",
  "dependencies": {
    "assert": "^1.4.1",// optional for us i don't even use it, install just in case
    "body-parser": "^1.18.1",// we need body-parser no matter what
    "cors": "^2.8.4", // for avoiding http header issue
    "express": "^4.15.4",
    "mongodb": "^2.2.31"
  }
}

 

then run command to install package and plugin we need with command below : 

npm install

 

step 2 : when installation succeed you will see notde_modules folder in your folder. now create app.js ( file name you can change as your like ) with code below : 

const express = require('express')
const bodyParser= require('body-parser')
const mongodb = require('mongodb')
const MongoClient = require('mongodb').MongoClient
const assert = require('assert')
const app = express()
const cors = require('cors')

app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({extended: true})) // support encoded bodies
app.use(cors({origin: '*'}))

var db

// this is connection to mongodb
MongoClient.connect('mongodb://localhost:27017/dbtest', (err, database) => {
  if (err) return console.log(err)
  db = database
})

// for send data to client (read)
app.get('/crud/read', (req, res, next) => {
  var cursor = db.collection('info').find({}).toArray(function(err, result) {
    if (err) throw err;
    // console.log(result);

    res.header("Access-Control-Allow-Origin", "*");
    res.send(result);

    //db.close();
  });
})

// for insert data from submit data of client (create)
app.post('/crud/insert', (reqs, resp, next) => {
  reqs.header("Access-Control-Allow-Origin", "*");
  // reqs.header("Access-Control-Allow-Header", "*");
  reqs.header("Access-Control-Allow-Methods", "POST");

  var obj = { name: reqs.body.name, dob: reqs.body.dob, gender: reqs.body.gender }; 
  var cursor = db.collection('info').insertOne(obj, function(err, res){
  	if (err) throw err;
    resp.send({log: "insert success !",data: obj});
    console.log(obj);
  	//db.close();
  });
  //console.log(JSON.parse(JSON.stringify(reqs.body)));
  console.log(reqs.body);
})

// for update data (update)
app.put('/crud/update/:UPid', (rqs, rsp, next) => {
  rqs.header("Access-Control-Allow-Origin", "*");
  rqs.header("Access-Control-Allow-Methods", "PUT");

  var obj = { "_id" : mongodb.ObjectID(rqs.params.UPid) };
  var update = { $set : { name: rqs.body.name, dob: rqs.body.dob, gender: rqs.body.gender} };  // $set is object 

  var cursor = db.collection('info').updateMany(obj,update, function(err, res){
    if (err) throw err;
    rsp.send({log: "update success !",data: obj});
    console.log(rqs.body);
    // console.log(update);
    //db.close();
  });
})

// for delete data from database (delete)
app.delete('/crud/delete/:DLid', (reqs, resp, next) => {
  var obj = { "_id": mongodb.ObjectID(reqs.params.DLid) }; 
  db.collection('info').deleteMany(obj, function(err, res){
    if (err) throw err;
    resp.send("delete success !");
    // console.log(reqs.params.DLid);
    //db.close();
  });
})

// our back-end side run on port 3000
app.listen('3000', () => {
    console.log('listening on 3000')
})

 

save file and then try to run with command below ( if no error you will see log 'listening on 3000') : 

node app.js

 

if no probelm , we done on backend side (we called it server). now it is time for our client side

Part 2 : Client side

step 1 : we don't create package.json and add json object to install package anymore but you can do that if you want. we just need to run initialize command call host package that we already have. before you can initialize you must install vue-cli from it online host. now follow command below carefully : 

// install global vue-cli to enable to initialize package (run it if you don't have vue in your pc)
npm install --global vue-cli

// this command below is used to created project that we call initialize
vue init webpack my-project

in our project we vue-router , vue-axios , query-string . so install them after you initialize project package ok ? have command below : 

npm install --save axios vue-axios //https://www.npmjs.com/package/vue-axios

npm install --save vue-router // if your hand slip to check NO

npm install --save query-string // https://www.npmjs.com/package/query-string

 

step 2 : after take long time to initialize project and install plugin , please open file project/src/main.js and add follow code (only some part , check yourself)

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

 

step 3 : open file project/src/App.vue (if don't have , you need to create one) and add some part too : 

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <hr>
    <router-link to="/">Home</router-link> / 
    <router-link to="/crud">Crud</router-link> <!--add here-->
    <hr>
    <router-view></router-view> <!--here is where our component load where we click on router-link-->
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 

step 4 : we create new file crud.vue in directory project/src/components/ with code below : 

<template>
  <div id="crud">
    <h1 style="margin-bottom: 15px">CRUD VUE.JS 2 WITH NODE.JS ( MONGODB )</h1>
    <div class="container">
        <div class="row">
            <div class="col-md-8" style="border-right: 1px solid silver">
                <table class="table table-bordered table-striped">
                    <thead>
                      <th style="text-align: center">Name</th>
                      <th style="text-align: center">DOB</th>
                      <th style="text-align: center">Gender</th>
                    </thead>
                    <tr v-for="item in items">
                      <td>{{ item.name }}</td>
                      <td>{{ item.dob }}</td>
                      <td>{{ item.gender }}</td>
                      <td><button class="btn btn-warning" v-on:click="setUpdate(item)">edit</button></td>
                      <td><button class="btn btn-danger" v-on:click="remove(item)">delete</button></td>
                    </tr>
                </table>
            </div>
            <!-- {{ items }} -->
            <div class="col-md-4">
              <div class="form-group">
                <span><b>{{ action }}</b></span>
                <hr>
                <input class="form-control" style="margin-bottom: 20px" type="text" name="name" v-model="name" placeholder="name" />
                <select class="form-control" style="margin-bottom: 20px" v-model="gender">
                  <option selected value="">gender</option>
                  <option value="male">Male</option>
                  <option value="female">Female</option>
                </select>
                <input class="form-control" style="margin-bottom: 20px" type="date" name="dob" v-model="dob" placeholder="date of birth" />
                <button class="btn btn-outline-primary" v-on:click="createItem">create</button>
                <button class="btn btn-outline-warning" v-on:click="updateItem">update</button>
                <button class="btn btn-outline-danger">delete</button>
              </div>
            </div>
        </div>
    </div>
  </div>
</template>

<script>

import qs from 'query-string' // we use it because it cannot declare as global components

export default {
  data: function () {
    return {
      items: [],
      name: '',
      dob: '',
      gender: '',
      updateId: '',
      action: 'New item',
      update_id: '',
      backup: {} // used to save old value to search
    }
  },
  methods: {
    getItems: function () {
      this.axios.get('http://localhost:3000/crud/read', {
        header: {
          'Accept': 'application/json',
          'Access-Control-Allow-Origin': '*'
        }
      }).then((resp) => {
        this.items = resp.data
      })
    },
    createItem: function () {
      var obj = {'name': this.name, 'dob': this.dob, 'gender': this.gender}
      var strngObj = qs.stringify(obj)
      this.axios.post('http://localhost:3000/crud/insert',
      strngObj, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
      ).then((resp) => {
        if (resp.data.log === 'insert success !') {
          this.items.push(resp.data.data)
          alert(resp.data.log)
        }
        console.log(resp.data) // check full object in browser console log
      })
    },
    updateItem: function () {
      var objUpdate = {'_id': this.update_id, 'name': this.name, 'dob': this.dob, 'gender': this.gender}
      var strngObj = qs.stringify(objUpdate)
      var index = this.items.indexOf(this.backup) // search object in array by using backup object in function setUpdate
      this.axios.put('http://localhost:3000/crud/update/' + this.update_id,
      strngObj, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
      ).then((resp) => {
        if (resp.data.log === 'update success !') {
          this.items[index].name = objUpdate.name
          this.items[index].dob = objUpdate.dob
          this.items[index].gender = objUpdate.gender
          alert(resp.data.log)
          // console.log(resp.data.log)
        }
      })
    },
    setUpdate: function (e) { // setting when we click edit, put data to parame to update
      this.action = 'Update item ' + e.name
      this.update_id = e._id
      this.name = e.name
      this.dob = e.dob
      this.gender = e.gender
      this.backup = e
    },
    remove: function (e) { // setting when we click edit, put data to parame to update
      this.axios.delete('http://localhost:3000/crud/delete/' + e._id, { id: e._id }, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
      // emulateJSON: true // fix cannot post as form data and urlencoded
      ).then((resp) => {
        var index = this.items.indexOf(e)
        this.items.splice(index, 1)
        // alert(resp.data.log)
        console.log(index)
        console.log(e)
          // console.log(resp.data) // check full object in browser console log
      })
    }
  },
  created: function () {
    this.getItems() // method1 will execute at pageload
  }
}
</script>

<style>

</style>

be careful with eslint rule.

 

step 5 : route setting look below : 

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import Crud from '@/components/Crud'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    },
    {
      path: '/crud',
      name: 'Crud',
      component: Crud
    }
  ]
})

 

final : add bootstrap to index.html as normally for html css design : 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>vuecrud</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
  </body>
</html>

 

in the end save and run command to test : 

npm run dev

if you have error it will show on cmd log and broswer debugger log. that's it if you don't have errors you will result like image and video below.

 

Share this Post:

Related Posts:

www.000webhost.com