0

I have a series of checkboxes setup in Vue.js components that are emitting data to my parent element. I want to watch this data for changes and append the data within the object to an API call, in order to filter data.

Here's what my data on the parent element looks like when some items are checked (otherwise it's just an empty object if nothing's checked):

image of selectedFeatures object

I want to be able to insert this data into an API call that would (in general) look like this, when the data changes:

this.axios.get('http://localhost:8000/api/v1/schools' + 
    for (feature in selectedFeatures) {
        '?features[]=' + feature
    }
).then((response) => {
    this.$root.$emit('searchQuery', response.data);
});

Usually this is pretty easy with the Watch feature of Vue, but since my data is nested in unnamed arrays and generated dynamically, I'm not sure how to do this.

4
  • not sure it would help in your case but have you tried deep watching? vuejs.org/v2/api/#watch in the example c: is deep watching...so you want the api to be called automatically? Commented Jun 1, 2017 at 2:15
  • Your for-loop is being concatenated to a string? Please post the code for the components. Commented Jun 1, 2017 at 3:05
  • I tried deep watching, it doesn't seem to matter whether it's there or not, it only functions when I first load all the options, which doesn't seem to make sense to me, because the data doesn't change at that point... The for-loop I included is just an example of how I'd want it to work. I haven't written it yet, as I'm just trying to get some feedback via console log that the function is even working on data change. Here's a gist of the main parts of the parent component, plus the two checkbox components: gist.github.com/DinsmoreDesign/5e5002559e706ac2c57aa4530ee1f1d1 Commented Jun 1, 2017 at 16:35
  • So, I think I have a better idea, actually... I just emitted an event from the checkbox component that the filter component can catch. Every time it's emitted, it can update the API call from the data on the filter component. This way I don't even have to watch the data and deal with the nested parts of it. Commented Jun 1, 2017 at 17:46

1 Answer 1

2

Fixed by adding the following to Filters.vue's tags:

methods: {
    addFeatures() {
        var featureNames = '';
        // Loop through selectedFeatures and return a string of all features
        for (var key in this.selectedFeatures) {
           var obj = this.selectedFeatures[key];
           for (var prop in obj) {
               // Remove spaces and add + sign
               featureNames += '&features[]=' + obj[prop].split(' ').join('+');
           }
        };
        return 'http://localhost:8000/api/v1/schools?' + this.selectedGrade + '=1' + featureNames;
    }
},
mounted() {
    // When checkUpdated is emited, run new API call
    this.$root.$on('checkUpdated', function() {
        var gradeFeatures = this.addFeatures();
        // Dump string from addFeatures into end of API and send it to the root to filter out data
        this.axios.get( gradeFeatures ).then((response) => {
            this.$root.$emit('searchQuery', response.data);
        });
    }.bind(this));
}

I then changed the Checkbox.vue slightly by replacing:

<input type="checkbox" :disabled="disabled" :name="name" v-model="newValue" @change="$emit('change', newValue, $event)">

to:

<input type="checkbox" :disabled="disabled" :name="name" v-model="newValue" @change="valueChanged">

and added:

methods: {
    valueChanged() {
        this.$root.$emit('checkUpdated');
        this.$emit('change', this.newValue, this.$event);
    }
}

Which the mounted lifecycle can catch on the Filters.vue file to fire the method.

Works great!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.