Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Vlad Tanasie
Vlad Tanasie
7,201 Points

How can I make VueJS get in real time the updates i make to the database?

I am making this Vue JS todo app, i can edit the database but the front end does not get the updates, i have to refresh the page to see them, should i make the updateTodo() function async?

the stackoverflow to my problem -> https://stackoverflow.com/questions/56238577/how-can-i-make-vue-js-get-the-updates-i-make-to-the-database-in-real-time

<template lang="html">
  <div>
    <form v-on:submit='addTodo($event)'>
      <input type='text' placeholder='Enter Todo' v-model='newTodo'/>
      <input type='submit' />
    </form>
    <ul> 
      <li v-for='todo in todos' :key='todo._id'>
        <input type="checkbox">
        {{todo}}
        <button @click="deleteTodo(todo._id)">Delete</button>
        <button @click="updateTodo(todo._id)">Update</button>
      </li>
    </ul>
  </div>
</template>

<script>
import ToDoAPI from '@/services/ToDoAPI.js'
export default {
  data () {
    return {
      newTodo: '',
      todos: []
    }
  },
  mounted () {
    this.loadTodos()
  },
  methods: {
    async addTodo (evt) {
      evt.preventDefault() // prevents the form's default action from redirecting the page
      const response = await ToDoAPI.addTodo(this.newTodo)
      this.todos.push(response.data)
      this.newTodo = '' // clear the input field
    },
    async loadTodos () {
      const response = await ToDoAPI.getToDos()
      this.todos = response.data
    },
    deleteTodo(todoID){
        ToDoAPI.deleteTodo(todoID)
        //remove the array element with matching id
        this.todos = this.todos.filter(function(obj){
            return obj._id !== todoID
        })
    },
    //add an update function to update each todo
    updateTodo(todoID, edit){
      ToDoAPI.updateTodo(todoID, this.newTodo);
    }
  }
}
</script>

<style lang="css">
</style>
//express serverside
//get the todos to display (READ)
app.get("/todo", (req, res) => {
    const collection = client.db('todoapp').collection("todos"); //connecting to the atlas collection

    collection.find().toArray(function (err, results){ //filtering the results
        if(err){
            console.log(err)
            res.send([])
            return
        }

        res.send(results)
    })
})
//add a todo (CREATE)
app.post('/addTodo', (req, res) => {
    const collection = client.db('todoapp').collection('todos')
    let todo = req.body.todo //parse the data from the request body
    collection.insertOne({title: todo}, function(err, results) {
        if (err){
            console.log(err);
            res.send('');
            return
        }
        res.send(results.ops[0]) //retruns the new document
    })
})


//delete a todo (DELETE)
app.post('/deleteTodo', (req, res) => {
    const collection = client.db('todoapp').collection('todos');
    // remove the document by the unique id
    collection.removeOne({'_id': mongo.ObjectID(req.body.todoID)}, function(err, results){
        if(err) {
            console.log(err)
            res.send('')
            return
        }
        res.send()
    })
})

// add an update functio to update the existing mongodb data by its unique id
//update a todo (UPDATE)
app.post('/updateTodo', (req, res) => {
    const collection = client.db('todoapp').collection('todos');
    let todo = req.body.todo;
    console.log(todo + " is not a null value")
    collection.updateOne({'_id': mongo.ObjectID(req.body.todoID)}, {$set: {title: todo}}, function(err, results){
        if(err) {
            console.log(err)
            res.send('')
            return
        }
        res.send()
    }) 
})
//axios
export default {
  getToDos () {
    return API().get('todo') // connecting to the api
  },
  addTodo (todo) {
    return API().post('addTodo', {
      todo: todo // add our data to the response body
    })
  },
  deleteTodo (todoID) {
    return API().post('deleteTodo', {
      todoID: todoID // add data to the request body
    })
  },
  updateTodo (todoID) {
    return API().post('updateTodo', {
      todoID: todoID // add data to the request body
    })
  }

}

2 Answers

Seth Kroger
Seth Kroger
56,413 Points

The main issue is you aren't updating this.todos in updateTodo() like you are in the other methods. You do have a few options. One, you can search for the item by todoID and update it using $set(). Another, you can call loadTodos() after updating. I'd only recommend auto-refreshing if there were database updates coming from other sources than your front-end or it multiple users could edit the same todo list.

Kevin Gates
Kevin Gates
15,052 Points

You need to let your front-end know about these updates. One way is you could have an auto-refresh function. Like a loop that every X amount of time, you do an asynchronous fetch to the database to get the latest information.