Nico
Nico

Reputation: 131

VueJS computed property not updating on DOM

I'm trying to do a file upload with VueJS. When a file is added to the input field it is buffered and saved in the vuex store.

I'm positive that the state updates, this shows in vue-devtool and I added a button to check it.

The DOM however is not re-rendering on the state change. I tried it both with the buffer array and just a regular string. (when I click the commit button in vue-dev tools it updates the dom)

Please refer to this screenshot for a demonstration of the issue (this is after selecting a file and clicking the "console log state" button). Demonstration

Component

<template>
  <div id="home">
    <h3>Upload Book (pdf)</h3>
    <form v-on:submit="">
      <input v-on:change="captureFile" type="file" placeholder="Select file..." />
      <button type="submit">Upload</button>
      <p>
        <button v-on:click="consoleLog">Console log state</button>
        {{filebuffer}}
      </p>
    </form>

  </div>
</template>

<script>
export default {
  name: 'home',
  computed: {
    filebuffer () {
      return this.$store.state.fileBuffer
    }
  },
  methods: {
    captureFile (event) {
      let file = event.target.files[0]
      let reader = new window.FileReader()
      reader.readAsArrayBuffer(file)
      reader.onloadend = () => {this.$store.dispatch('loadBuffer', reader)}
    },
    consoleLog () {
      console.log(this.$store.state.fileBuffer)
    }
  }
}
</script>

Store

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'

Vue.use(Vuex)

export const store = new Vuex.Store({
  strict: true,
  state,
  mutations: {
    saveBuffer (state, payload) {
      state.fileBuffer = 'this will not update on the DOM'
      console.log('saveBuffer committed', payload)
    }
  },
  actions: {
    loadBuffer ({commit}, payload) {
      let buffer = Buffer.from(payload.result)
      commit('saveBuffer', buffer)
    }
  }
})

Upvotes: 2

Views: 1440

Answers (1)

Majed Fayazi
Majed Fayazi

Reputation: 553

you need to use Getters.

computed: {
  filebuffer () {
    return this.$store.getters.filebuffer;
  }
}

and inside your store file

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex)

// State
const state = {
    fileBuffer : '',  
}

// Mutate the State
const mutations = {
     saveBuffer (state, value) {
        state.fileBuffer = value
 } 

// Access The State
const getters = {
    fileBuffer : state => {
        return state.fileBuffer 
    }
}

const actions = {
   loadBuffer ({commit}, payload) {
     let buffer = Buffer.from(payload.result)
     commit('saveBuffer', buffer)
   }
}

const module = {
    state,
    getters,
    mutations,
    actions
};

export default module;

Hope this help solve your problem .

Upvotes: 1

Related Questions