khany
khany

Reputation: 1187

How to pass data from Vue instance to component

First I must say I have spent hours on this so if I have overlooked something stupidly simple then I do apologise.

I am trying to get one component to talk to another via the root Vue instance. So far I have managed to get the MakeComponent to send a message to the root instance as shown below:

const eventHub = new Vue() // Single event hub

// Distribute to components using global mixin
Vue.mixin({
    data: function () {
        return {
            eventHub: eventHub
        }
    }
});

Vue.component('fig-make-dropdown', require('./components/FigMakeDropdown.vue'));
Vue.component('fig-model-dropdown', require('./components/FigModelDropdown.vue'));

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the body of the page. From here, you may begin adding components to
 * the application, or feel free to tweak this setup for your needs.
 */
const app = new Vue({
    el: '#app',

    data: function() {
        return {
            makes: {},
            make: '',
            componentMake: ''
        };
    },

    mounted() {
        this.eventHub.$on('broadcast_make', data => {
            // do your thing
            console.log('parent', data);
            this.make = data;

        });
    }

});

The this.eventHub.$on successfully outputs the make value passed in. What I want to do is send that to the ModelComponent so that it can reload the select input with data from an ajax call using that make variable.

Here is the html snippet:

<fig-model-dropdown v-bind:make="make" make="{{ $value->make_id }}" model="{{ $value->model_id }}"></fig-model-dropdown>

And here is the ModelComponent:

<template>
    <div>
        <label for="make_model_id">Model</label>
        <select id="make_model_id" name="make_model_id" class="form-control" v-model="componentModel">
            <option value=""></option>
            <option :value="model.id" v-for="model in models">{{ model.name }}</option>
        </select>
    </div>
</template>

<script>
    export default {

        props: {
            'make':'',
            'model': {
                'default': ''
            }
        },

        data: function() {
            return {
                componentMake: '',
                componentModel: '',
                models: {}
            };
        },

        created: function() {
            console.log('fig-model-dropdown Component ready.');
            if(this.make) {
                console.log('MAKE', this.make);
                this.componentMake = this.make;
                this.fetchModelsByMake();
            }
            if(this.model) {
                this.componentModel = this.model;
            }
        },

        methods: {
            fetchModelsByMake: function() {
                this.$http.get('/api/make/models/' + this.make ).then(
                    function (models) {
                        this.models = models.body;
//                      console.log('MODEL', this.model);
                    }, function (error) {
                            // handle error
                    }
                );                  
            }
        }

    }
</script>

With this code I get no errors but no apparent indication that the ModelComponent has received it. How do i now pass the make into the ModelComponent and rebuild the select?

Upvotes: 3

Views: 1075

Answers (1)

Saurabh
Saurabh

Reputation: 73659

It seems this is happening because your this is not pointing to correct scope in fetchModelsByMake method. scope of this will change inside a 'this.$http' call, so you just have to do something like following:

        fetchModelsByMake: function() {
            var self = this
            this.$http.get('/api/make/models/' + this.make ).then(
                function (models) {
                    self.models = models.body;

// console.log('MODEL', this.model); }, function (error) { // handle error } );

You can also have a look at my similar answer here.

Upvotes: 1

Related Questions