Dave Bitter
Dave Bitter

Reputation: 101

How to update the props for a child component in Vue.js?

I have a parent component that will do an API call for some data. When the response gets back I update the data. I sent the data to a child component. This child component only renders the initial value, which is an empty array, but never the updated data. I know that in React updating a property will result in a re-render of the child component. How can I achieve this in Vue.js?

This is the parent component that will pass the data:

<template>
  <div id="app">
    <Table v-bind:users='users' />
  </div>
</template>

<script>
import Table from './components/Table'

export default {
  name: 'app',
  components: {
    Table
  },
  data () {
    return {
      users: []
    }
  },
  created: () => {
    fetch('http://jsonplaceholder.typicode.com/users').then((response) => {
      response.json().then((data) => {
        console.log(data)
        this.users = data
      })
    })
  }

}
</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>

This is the child component that will receive the data and update the view:

<template>
  <ul>
    <li v-for='user in users'>
      {{ user.name }}
    </li>
  </ul>
</template>

<script>
export default {
  name: 'Table',
  data () {
    return {
    }
  },
  props: ['users'],

}
</script>

<style scoped>

</style>

The fetch response looks like this:

[  
    {  
            "id":1,
            "name":"Leanne Graham",
            "username":"Bret",
            "email":"[email protected]",
            "address":{  
                "street":"Kulas Light",
                "suite":"Apt. 556",
                "city":"Gwenborough",
                "zipcode":"92998-3874",
                "geo":{  
                        "lat":"-37.3159",
                        "lng":"81.1496"
                }
            },
            "phone":"1-770-736-8031 x56442",
            "website":"hildegard.org",
            "company":{  
                "name":"Romaguera-Crona",
                "catchPhrase":"Multi-layered client-server neural-net",
                "bs":"harness real-time e-markets"
            }
    },
    {  
            "id":2,
            "name":"Ervin Howell",
            "username":"Antonette",
            "email":"[email protected]",
            "address":{  
                "street":"Victor Plains",
                "suite":"Suite 879",
                "city":"Wisokyburgh",
                "zipcode":"90566-7771",
                "geo":{  
                        "lat":"-43.9509",
                        "lng":"-34.4618"
                }
            },
            "phone":"010-692-6593 x09125",
            "website":"anastasia.net",
            "company":{  
                "name":"Deckow-Crist",
                "catchPhrase":"Proactive didactic contingency",
                "bs":"synergize scalable supply-chains"
            }
    },
    {  
            "id":3,
            "name":"Clementine Bauch",
            "username":"Samantha",
            "email":"[email protected]",
            "address":{  
                "street":"Douglas Extension",
                "suite":"Suite 847",
                "city":"McKenziehaven",
                "zipcode":"59590-4157",
                "geo":{  
                        "lat":"-68.6102",
                        "lng":"-47.0653"
                }
            },
            "phone":"1-463-123-4447",
            "website":"ramiro.info",
            "company":{  
                "name":"Romaguera-Jacobson",
                "catchPhrase":"Face to face bifurcated interface",
                "bs":"e-enable strategic applications"
            }
    },
    {  
            "id":4,
            "name":"Patricia Lebsack",
            "username":"Karianne",
            "email":"[email protected]",
            "address":{  
                "street":"Hoeger Mall",
                "suite":"Apt. 692",
                "city":"South Elvis",
                "zipcode":"53919-4257",
                "geo":{  
                        "lat":"29.4572",
                        "lng":"-164.2990"
                }
            },
            "phone":"493-170-9623 x156",
            "website":"kale.biz",
            "company":{  
                "name":"Robel-Corkery",
                "catchPhrase":"Multi-tiered zero tolerance productivity",
                "bs":"transition cutting-edge web services"
            }
    },
    {  
            "id":5,
            "name":"Chelsey Dietrich",
            "username":"Kamren",
            "email":"[email protected]",
            "address":{  
                "street":"Skiles Walks",
                "suite":"Suite 351",
                "city":"Roscoeview",
                "zipcode":"33263",
                "geo":{  
                        "lat":"-31.8129",
                        "lng":"62.5342"
                }
            },
            "phone":"(254)954-1289",
            "website":"demarco.info",
            "company":{  
                "name":"Keebler LLC",
                "catchPhrase":"User-centric fault-tolerant solution",
                "bs":"revolutionize end-to-end systems"
            }
    },
    {  
            "id":6,
            "name":"Mrs. Dennis Schulist",
            "username":"Leopoldo_Corkery",
            "email":"[email protected]",
            "address":{  
                "street":"Norberto Crossing",
                "suite":"Apt. 950",
                "city":"South Christy",
                "zipcode":"23505-1337",
                "geo":{  
                        "lat":"-71.4197",
                        "lng":"71.7478"
                }
            },
            "phone":"1-477-935-8478 x6430",
            "website":"ola.org",
            "company":{  
                "name":"Considine-Lockman",
                "catchPhrase":"Synchronised bottom-line interface",
                "bs":"e-enable innovative applications"
            }
    },
    {  
            "id":7,
            "name":"Kurtis Weissnat",
            "username":"Elwyn.Skiles",
            "email":"[email protected]",
            "address":{  
                "street":"Rex Trail",
                "suite":"Suite 280",
                "city":"Howemouth",
                "zipcode":"58804-1099",
                "geo":{  
                        "lat":"24.8918",
                        "lng":"21.8984"
                }
            },
            "phone":"210.067.6132",
            "website":"elvis.io",
            "company":{  
                "name":"Johns Group",
                "catchPhrase":"Configurable multimedia task-force",
                "bs":"generate enterprise e-tailers"
            }
    },
    {  
            "id":8,
            "name":"Nicholas Runolfsdottir V",
            "username":"Maxime_Nienow",
            "email":"[email protected]",
            "address":{  
                "street":"Ellsworth Summit",
                "suite":"Suite 729",
                "city":"Aliyaview",
                "zipcode":"45169",
                "geo":{  
                        "lat":"-14.3990",
                        "lng":"-120.7677"
                }
            },
            "phone":"586.493.6943 x140",
            "website":"jacynthe.com",
            "company":{  
                "name":"Abernathy Group",
                "catchPhrase":"Implemented secondary concept",
                "bs":"e-enable extensible e-tailers"
            }
    },
    {  
            "id":9,
            "name":"Glenna Reichert",
            "username":"Delphine",
            "email":"[email protected]",
            "address":{  
                "street":"Dayna Park",
                "suite":"Suite 449",
                "city":"Bartholomebury",
                "zipcode":"76495-3109",
                "geo":{  
                        "lat":"24.6463",
                        "lng":"-168.8889"
                }
            },
            "phone":"(775)976-6794 x41206",
            "website":"conrad.com",
            "company":{  
                "name":"Yost and Sons",
                "catchPhrase":"Switchable contextually-based project",
                "bs":"aggregate real-time technologies"
            }
    },
    {  
            "id":10,
            "name":"Clementina DuBuque",
            "username":"Moriah.Stanton",
            "email":"[email protected]",
            "address":{  
                "street":"Kattie Turnpike",
                "suite":"Suite 198",
                "city":"Lebsackbury",
                "zipcode":"31428-2261",
                "geo":{  
                        "lat":"-38.2386",
                        "lng":"57.2232"
                }
            },
            "phone":"024-648-3804",
            "website":"ambrose.net",
            "company":{  
                "name":"Hoeger LLC",
                "catchPhrase":"Centralized empowering task-force",
                "bs":"target end-to-end models"
            }
    }
]

Upvotes: 1

Views: 2511

Answers (2)

Dave Bitter
Dave Bitter

Reputation: 101

I've figured it out myself!

The problem was the syntax I was using.

I had:

created: () => {
fetch('http://jsonplaceholder.typicode.com/users').then((response) => {
  response.json().then((data) => {
    console.log(data)
    this.users = data
  })
})

}

I changed it to:

created() {
    fetch('http://jsonplaceholder.typicode.com/users').then((response) => {
        response.json().then((data) => {
            console.log(data)
            this.users = data
        })
    })
}

I guess it's just a binding issue with the es6 fat arrow.

Upvotes: 3

Hardik Satasiya
Hardik Satasiya

Reputation: 9693

You can check it in this example, its ractive when you set props it will pass to child automatically and trigger re-render

Vue.component('child', {
  template: '#child', 
  props: ['users']
});

new Vue({
  el: '#app',
  data: {
    users: []
  },
  created: function() {
    var vm = this;
    setTimeout(function() {
        vm.users = [{ name: 'hardik'}, { name: 'someone'}];
    }, 2000)
  },
  methods: {
     
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>

<div id="app">  
  <child :users="users"></child>  
</div>

<template id="child">
   <ul>
    <li v-for='user in users'>
      {{ user.name }}
    </li>
  </ul>
</template>

Upvotes: -2

Related Questions