Home » vue » I have to update another component when I add data in another

I have to update another component when I add data in another

Posted by: admin November 26, 2021 Leave a comment

Questions:

When I add data using TaskForm I have to reload the page to see the effect maintained by CardComponent. I would like to see recently added data immediately. What is the best way to achieve this result?

I have to post code of my two components, so I’m using Pastebin

TaskForm: https://pastebin.com/HVjwkAKd

CardComponent: https://pastebin.com/PM00TzRq

I’m not good at using Vue, that is why I am asking for help. Thank you!

Answers:

This is a typical use case for state management with Vuex, a centralized singleton that provides reactive state across multiple components.

Two important points from the documentation are:

  • Vuex stores are reactive. When Vue components retrieve state from it, they will reactively and efficiently update if the store’s state changes.

  • You cannot directly mutate the store’s state. The only way to change a store’s state is by explicitly committing mutations. This ensures every state change leaves a track-able record, and enables tooling that helps us better understand our applications.

This example shows how to commit mutations and observe state changes in components:

Vue.use(Vuex)

const baseComponent = {
  props: ['resource'],
  data: () => ({
    loading: false
  }),
  computed: {
    title () {
      return this.resource.charAt(0).toUpperCase() + this.resource.slice(1) + ' Component'
    },
    btnText () {
      return this.loading ? `Fetching ${this.resource}...` : `Fetch ${this.resource}`
    }
  },
  methods: {
    async fetchResource() {
      this.loading = !this.loading

      const resources = await fetch(`https://jsonplaceholder.typicode.com/${this.resource}`)
        .then(response => response.json())
        .then(resources => resources)

      this.$store.commit(`set${this.resource.charAt(0).toUpperCase() + this.resource.slice(1)}`, resources)

      this.loading = !this.loading
    }
  },
  template: `<div>
  <h1>{{ title }}</h1>
  <button @click="fetchResource" :disabled="loading">{{ btnText }}</button>
  <p>Total Posts: {{ $store.getters['getPosts'].length }}</p>
  <p>Total Todos: {{ $store.getters['getTodos'].length }}</p>
  </div>`
}

Vue.component('component-a', baseComponent)
Vue.component('component-b', baseComponent)

const store = new Vuex.Store({
  state: {
    posts: [],
    todos: []
  },
  getters: {
    getPosts: (state) => state.posts,
    getTodos: (state) => state.todos,
  },
  mutations: {
    setPosts: (state, posts) => {
      state.posts = posts
    },
    setTodos: (state, todos) => {
      state.todos = todos
    }
  }
})

new Vue({
  el: '#app',
  store
})
#app {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex"></script>

<div id="app">
  <component-a resource="posts"></component-a>
  <component-b resource="todos"></component-b>
</div>

###

I decided to use bus, because my project isn’t large. Now it looks like this:

TaskForm:

methods:{

            addTask() {
                EventBus.$emit('taskCreated',{title:this.title, second_title:this.second_title});
                axios.post('./api/word', {
                    title:this.title,
                    second_title:this.second_title
                     })

                 }

CardComponent:

created(){

          axios.get('./api/word')
                .then(response => this.words = response.data);        


          EventBus.$on('taskCreated', (title,second_title) => {

              this.words.push(title);

              this.words.push(second_title);           


              axios.get('./api/word')
                .then(response => this.words = response.data);


          });

And my problem is the repetition of code in CardComponent. When the code with axios is not present in created(), nothing generates. If I ommit this code in EventBus section, I can’t see automatic updates. But when I use this code, sometimes there is no visible update, and sometimes instead of adding one task, there appears two or three of them (and they are of course the same). Any ways to deal with my problem?