bencarter78
bencarter78

Reputation: 3895

Updating VueJS component data attributes when prop updates

I'm building a VueJS component which needs to update the data attributes when a prop is updated however, it's not working as I am expecting.

Basically, the flow is that someone searches for a contact via an autocomplete component I have, and if there's a match an event is emitted to the parent component.

That contact will belong to an organisation and I pass the data down to the organisation component which updates the data attributes. However it's not updating them.

The prop being passed to the organisation component is updated (via the event) but the data attibute values is not showing this change.

This is an illustration of my component's structure...

enter image description here

Here is my code...

Parent component

    <template>
        <div>
            <blink-contact
                    :contact="contact"
                    v-on:contactSelected="setContact">
            </blink-contact>

            <blink-organisation 
                    :organisation="organisation" 
                    v-on:organisationSelected="setOrganisation">
            </blink-organisation>
        </div>
    </template>

    <script>
        import BlinkContact from './BlinkContact.vue'
        import BlinkOrganisation from './BlinkOrganisation.vue'

        export default {
            components: {BlinkContact, BlinkOrganisation},

            props: [
                'contact_id', 'contact_name', 'contact_tel', 'contact_email',
                'organisation_id', 'organisation_name'
            ],

            data () {
                return {
                    contact: {
                        id: this.contact_id,
                        name: this.contact_name,
                        tel: this.contact_tel,
                        email: this.contact_email
                    },

                    organisation: {
                        id: this.organisation_id,
                        name: this.organisation_name
                    }
                }
            },

            methods: {
                setContact (contact) {
                    this.contact = contact
                    this.setOrganisation(contact.organisation)
                },

                setOrganisation (organisation) {
                    this.organisation = organisation
                }
            }
        }
    </script>

Child component (blink-organisation)

        <template>
        <blink-org-search
                field-name="organisation_id"
                :values="values"
                endpoint="/api/v1/blink/organisations"
                :format="format"
                :query="getQuery"
                v-on:itemSelected="setItem">
        </blink-org-search>
    </template>

    <script>
        export default {
            props: ['organisation'],

            data() {
                return {
                    values: {
                        id: this.organisation.id,
                        search: this.organisation.name
                    },
                    format: function (items) {
                        for (let item of items.results) {
                            item.display = item.name
                            item.resultsDisplay = item.name
                        }
                        return items.results
                    }
                }
            },

            methods: {
                setItem (item) {
                    this.$emit('organisationSelected', item)
                }
            }
        }
    </script>

How can I update the child component's data properties when the prop changes?

Thanks!

Upvotes: 3

Views: 3746

Answers (1)

Bert
Bert

Reputation: 82459

Use a watch.

watch: {
    organisation(newValue){
        this.values.id = newValue.id
        this.values.search = newValue.name
    }
}

In this case, however, it looks like you could just use a computed instead of a data property because all you are doing is passing values along to your search component.

computed:{
    values(){
        return {
            id: this.organisation.id
            search: this.organisation.name
        }
    }
}

Upvotes: 4

Related Questions