[Vuejs]-Vue.js: How to change booleanfield in specific object from false to true @click in state with mutations and server with actions axios?

0๐Ÿ‘

โœ…

My problem was that I tried to pass down 3 arguments to the actions payload in the store. The action accepts accepts only 1 argument which is the payload. I changed the axios method from PUT to PATCH.

Home.vue

<template>

<div class="container">

  <section class="hero is-link">
    <div class="hero-body">
      <div class="container">
        <h1 class="title">
          Hello Dudes
        </h1>
        <h2 class="subtitle">
          Hamster ToDo List
        </h2>
      </div>
    </div>
  </section>

<section class="section">

  <nav class="level">
    <div class="level-item has-text-centered">
      <div>
        <p class="heading">All Tasks</p>
        <p class="title">{{getTotalTodos}}</p>
      </div>
    </div>
    <div class="level-item has-text-centered">
      <div>
        <p class="heading">Tasks has to be done</p>
        <p class="title">{{getTodosFalse}}</p>
      </div>
    </div>
    <div class="level-item has-text-centered">
      <div>
        <p class="heading">Tasks finished</p>
        <p class="title">{{getTodosTrue}}</p>
      </div>
    </div>
    <!-- <div class="level-item has-text-centered">
      <div>
        <p class="heading">Likes</p>
        <p class="title">789</p>
      </div>
    </div> -->
  </nav>
</section>


<section class="section">
  <div class="columns">
    <div class="column is-half">
      <strong>Add ToDo</strong>
      <div class="control">
      <input class="input is-info" v-model="todoTitle" type="text" placeholder="Add Task Title">
      <input class="input is-info" v-model="todoBody" type="text" placeholder="Add Task Body">
      <button class="button is-link" @click="addTodoItem({title: todoTitle, body: todoBody, done: false}); empyInput()">Add</button>
    </div>
    </div>
  </div>

  <div class="tabs is-small">
    <ul>
      <li class="is-active"><a>All Tasks </a></li> <span class="tag is-link">{{getTotalTodos}}</span>
      <li><a>Tasks still not done</a></li><span class="tag is-link">{{getTodosFalse}}</span>
      <li><a>Finished Tasks</a></li><span class="tag is-link">{{getTodosTrue}}</span>
      <!-- <li><a>Documents</a></li> -->
    </ul>
  </div>

  <article class="media" v-for="todo in todoItems" :key="todo.id">
    <figure class="media-left">
      <!-- <p class="image is-64x64">
        <img src="https://bulma.io/images/placeholders/128x128.png">
      </p> -->
    </figure>
    <div class="media-content">
      <div class="content">
        <p>
          <strong>{{todo.title}}</strong>  
          <br>
            {{todo.body}}
        </p>
      </div>
      <nav class="level is-mobile">
        <div class="level-left">
          <a class="level-item">
            <span class="icon is-small"><i class="fas fa-edit"></i></span>
          </a>
          <a class="level-item" v-if="todo.done==false" @click="updateTodoToTrue(todo.id)">
            <span class="icon is-small"><i class="fas fa-check"></i></span>
          </a>
          <a class="level-item" v-if="todo.done==true" @click="updateTodoToFalse(todo.id)">
            <span class="icon is-small"><i class="fas fa-undo"></i></span>
          </a>

          <a class="level-item" @click="deleteTodoItem(todo.id)">
            <span class="icon is-small"><i class="fas fa-trash"></i></span>
          </a>
        </div>
      </nav>
    </div>
    <div class="media-right">
      <button class="delete" @click="deleteTodoItem(todo.id)"></button>
    </div>
  </article>


</section>

</div>


</template>


<script>
// @ is an alias to /src
import {mapGetters} from 'vuex';
import {mapActions} from 'vuex';

export default {
  name: 'Home',
  data() {
    return{
      todoTitle: '',
      todoBody: '',
    }
  },
  // updated() {
  //   this.$store.dispatch('getTodoItems');
  // },
  computed: {
   ...mapGetters(['todoItems', 'getTotalTodos', 'getTodosTrue', 'getTodosFalse']) 
  },
  methods: {
    ...mapActions(['addTodoItem', 'deleteTodoItem', 'updateTodoToTrue', 'updateTodoToFalse']),
    // addTodo() {
    //   return this.$store.actions.addTodoItem;
    empyInput() {
      this.todoTitle = '';
      this.todoBody = ''; 
    }
  }
}
</script>

STORE

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    todoItems: []
  },


  // Keep in mind that response is an HTTP response
  // returned by the Promise.
  // The mutations are in charge of updating the client state.
  mutations: {
    UPDATE_TODO_ITEMS (state, payload) {
      state.todoItems = payload;
    },
    ADD_TODO_ITEMS (state, payload) {
      state.todoItems.push(payload)
    },
    DELETE_TODO_ITEMS (state, payload) {
      state.todoItems.splice(payload, 1)
    },
    changeTodoStatus: (state, payload) => {
      let index = state.todoItems.findIndex(el => {
        return el.id == payload.id
      })
      state.todoItems[index].done = payload.done
    }

  },

  actions: {
    getTodoItems ({ commit }) {
      axios.get('http://127.0.0.1:8000/api/').then((response) => {
        commit('UPDATE_TODO_ITEMS', response.data)
      });
    },
    addTodoItem ({ commit }, todoItem) {
      axios.post('http://127.0.0.1:8000/api/', todoItem).then((response) => {
        commit('ADD_TODO_ITEMS', response.data)
      });
    },
    deleteTodoItem ({ commit }, todoItemId) {
      axios.delete('http://127.0.0.1:8000/api/' + todoItemId + '/').then((response) => {
        commit('DELETE_TODO_ITEMS', response.data)
      });
    }, 
    updateTodoToTrue ({ commit }, todoItemId) {
      var payload = {
        done: true
      };
      axios.patch('http://127.0.0.1:8000/api/' + todoItemId + '/', payload).then((response) => {
        commit('changeTodoStatus', response.data)
      });
    },   
    updateTodoToFalse ({ commit }, todoItemId) {
      var payload = {
        done: false
      };
      axios.patch('http://127.0.0.1:8000/api/' + todoItemId + '/', payload).then((response) => {
        commit('changeTodoStatus', response.data)
      });
    },   
  },

  getters: {
    todoItems: state => state.todoItems,
    getTotalTodos: state => state.todoItems.length,
    getTodosTrue: state => state.todoItems.filter(todo => todo.done).length,
    getTodosFalse: state => state.todoItems.filter(todo => !todo.done).length
  },

  modules: {
  }
})

Leave a comment