Vue.js parent component sending new data: prop mutation detected

Encountering an issue in the console with the following error message:

Instead, use a data or computed property based on the prop's value. Prop being mutated: "sortType"

Within my root file, I have an API and filter function sending data to components. Everything was working smoothly until I introduced sorting in the filterList() method.

This is how I am handling the sortType:

<div id="toprow">
       // slider codes...
        <select id="sortBox" v-model="sortData" v-on:change="filterList">
            <option value="">sorting</option>
            <option value="price">cheapest</option>
            <option value="created_at">newest</option>
        </select>
</div>


props:["filterList", "slider", "sliderX", "sortType"],
components: {
    vueSlider,
},
data() {
    return {
        sortData: this.sortType
    }
},
methods: {
    filterList(newType){
        this.$emit('update:type', newType)
    }
}

Continuing from the root file...

<app-toprow v-on:update:type="sortType = $event" :filterList="filterList" :slider="slider" :sliderX="sliderX" :sortType="sortType"></app-toprow>


data(){
    return {
        api: [],
        sortType:"",
    }
},
mounted(){
    axios.get("ajax").then(response => {
        this.api = response.data
    })
},
methods: {

},
computed: {
    filterList: function () {
        let filteredStates = this.api.filter((estate) => {
            return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
            (this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
            (this.regions.length === 0 || this.regions.includes(estate.region))});

            if(this.sortType == 'price') {
                filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
            }
            if(this.sortType == 'created_at') {
                filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
            }

            return filteredStates;
    },
}
}

Is there a mistake in how I am handling the sortType variable?

Answer №1

When passing sortType as a prop into the child component and modifying it using v-model in select, an error may occur.

An example of how your child component should look like:

<div id="toprow">
// slider codes...
    <select id="sortBox" v-model="selectedSort" v-on:change="filterList">
        <option value="">sorting</option>
        <option value="price">cheapest</option>
        <option value="created_at">newest</option>
     </select>
</div>


export default {
    data() => ({
        selectedSort: this.sortType
    })
    props:["filterList", "slider", "sliderX", "sortType"],
    components: {
        vueSlider,
    },
    methods: {
        filterList(newType){
            this.$emit('update:type', newType)
        }
    }
}

Make sure to emit a custom event on the parent when changing the sorting with v-on:change=filterList.

In the parent component, you can include something like this:

<app-toprow v-on:update:type="sortType = $event" :filterList="filterList" :slider="slider" :sliderX="sliderX" :sortType="sortType"></app-toprow>

For more information, visit the following resources: SO question, Vue Docs - Custom Events, Vue Docs - One-Way Data Flow

Answer №2

Is the default value for the select option always "sorting" when the page loads? If so, you don't need to use v-model.

If it does have a default value, try using :value instead of v-model and set the prop sortType as the value.

Make sure not to use the same name for filterList; use a different variable for the function.

<div id="toprow">
       // slider codes...
        <select id="sortBox" :value="sortType" v-on:change="change">
            <option value="">sorting</option>
            <option value="price">cheapest</option>
            <option value="created_at">newest</option>
        </select>
</div>

In the change Function

export default {
    methods: {
        change(e){
            this.$emit('update:type', e.target.value)
        }
    }
}

In your parent component

<app-toprow v-on:update:type="sortType = $event" :filterList="differentVariableName" :slider="slider" :sliderX="sliderX" :sortType="sortType"></app-toprow>

Answer №3

SOLUTION FOR CLONED[i].apply ERROR

Dealing with the Uncaught TypeError: cloned[i].apply is not a function at HTMLInputElement.invoker (vue.esm.js?65d7:1810) error in Vue 2

Instead of using the prop name filterList, consider renaming it to avoid conflicts.

UPDATED SOLUTION

In this revised answer, it is suggested that the method and prop names should not match as it can cause conflicts. It is also recommended to not pass the filterList method from parent to child components if you are already listening for changes on it via update:type.

methods: {
    filterList(event){
        // utilize the v-model reactive feature..
        this.$emit('update:type', this.sortData)
        // if you prefer not to use this.sortData -> uncomment the following line
        // this.$emit('update:type', event.target.value)
    }
}

PREVIOUS SUGGESTION

Consider utilizing mounted() to initialize sortData with this.sortType instead of assigning it directly in the data object.

data() {
    return {
        sortData: null
    }
},
mounted() {
  this.sortData = this.sortType
}

Additional Note:

A personal theory... The issue could be related to Vue's reactivity principles where modifying data values directly from props may lead to unexpected behavior. It might be worth exploring this further in future investigations.

If in doubt, seek clarification from other sources.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to include a variable in the URL for an AJAX call?

When working with a PHP function that requires an ID and adding a variable to the Ajax URL, the following code snippet can be helpful: PHP Code: function get_json_selected($purpose) { $ids = explode(",", $this->input->post("ids")); ...

Using AngularJS, you can easily preselect an option in a select menu that is populated using ng-options

Exploring how to use AngularJS ng-option directive to populate a select menu and set a default option. The JSON data retrieved by AngularJS: {"AF":"Afghanistan","AX":"\u00c5land Islands","AL":"Albania","DZ":"Algeria","AS":"American Samoa","AD"} The ...

What is the best way to implement a scroll to top/bottom button globally in Vue?

I have created a scroll-to-top and scroll-to-bottom button for my application. However, I want to make these buttons accessible globally throughout the app without having to repeat the code in every page where the component is needed. Currently, I am inclu ...

How to Condense an Element Using Position: Absolute

https://i.sstatic.net/GMUss.png I'm attempting to create functionality where the "Open Chat" button displays an Absolute positioned div, then hides it when clicked again. I experimented with using the react-collapse component, but encountered issues ...

Why does serializing a JavaScript Object to JSON result in "{}"?

Hello fellow developers, I'm currently working on setting up a LocalStorage feature for my web application. One issue I've come across is that all objects in the Model abstraction layer need to be serialized. I understand that functions aren&a ...

The Alchemy feature on hover is not functioning

I am currently using alchemy.js to display a graph, but I am encountering issues with showing the "onMouseOver" caption of the graph's node. The console is displaying some errors which you can see here. Here is the code snippet: <html> < ...

Invalid template detected within the Kendo dropdown component

I am trying to create a template that will only be displayed if the data value is "Low". This is how I have set up my template column: template: '# if( data=="Low" ){#<span><i class="fa fa-square blue"></i> <span># } ' U ...

Assign a value to the active textbox using JavaScript

Hello everyone, I am working on a page with three textboxes and one listbox. I would like to have functionality where if the user clicks on the first textbox and then selects an item from the list, that selected item should be automatically set as th ...

Stopping the spread of popup alerts: A comprehensive guide

I'm having trouble explaining this in English;-) Whenever I select an option, an alert pops up for each choice and I don't know how to stop it. Step 1: Choose the "aaaa" option, for example 1111 alert ... Step 2: Choose the "bbbb" option, for ...

Alert: Mouse Exiting Window - Moodle Prompt

I have created an online exam using the Moodle platform, coded in PHP. I am now looking for a way to prevent test-takers from navigating away from the test by implementing a mouseover pop-up. Below is the code I have for triggering an alert pop-up when th ...

A guide on organizing the visible items in a vue table

I need help with two issues related to this code snippet. 1. The first problem arises when I have an array containing four items with IDs [1, 2, 4, 5, 7]. If I select to display 2 items per page and click on the sort function, it shows entries with IDs 1& ...

Looking for guidance on where to find a functional code sample or comprehensive tutorial on working with ViewMetadata in Angular2

I am currently trying to understand the relationship between viewmetadata and the fundamental use of encapsulation: ViewEncapsulation, including ViewEncapsulation.Emulated and ViewEncapsulation.None. Here is a link for further information: https://angula ...

Encountering numerous TypeScript errors due to a JavaScript file in Visual Studio 2017

Kindly review the update below I utilized the following package as a foundation for my VS Project -> https://github.com/AngularClass/angular2-webpack-starter Everything ran smoothly in Visual Studio Code, but when I attempted to convert it into a Visu ...

Having trouble transforming the JSON object into a usable format

Although I'm still getting the hang of JSON, please bear with me if this seems like a rookie mistake. My approach involves sending a query to a local file that performs a cURL operation on an external site's API and returns a JSON object. Due to ...

Tips on fetching the ID of the selected option using JavaScript without relying on jQuery

Looking to print the selected option ID using pure Javascript (not JQuery) for multiple select tags. If we have more than one select tag, how do we achieve this? <select onchange="showOptions(this)" id="my_select1"> <option value="a1" id="ida ...

Utilizing the "::first-letter" pseudo element selector in conjunction with the MuiButton class in Material UI - What is the process?

Is it possible to change the text case of Button text inside Material UI Button to sentence case with CSS? https://mui.com/components/buttons/ The text inside the button - ADD FRIEND should be transformed to sentence case as Add friend. I attempted to o ...

The functionality of a Vue custom tooltip behaves strangely after clicking the button multiple times

I created this custom tooltip code that automatically closes after 2 seconds when a user clicks on a button, not just hovers over it. Initially, it works perfectly for the first two clicks, but then starts behaving strangely from the third click onwards. ...

Issue encountered during upgrade from version 10 to version 13 in a Next.js migration: Module not found

I've been working on upgrading our old site from version 10 to version 13, and we have a custom backend built with express. However, I keep encountering a "Module not found" error when running the project concurrently, specifically when running the cl ...

Struggling to send information to a centralized object through props, unable to render the data

I've come across an issue while attempting to transfer data from a component to a global object. The component is functioning correctly, but the author information is not displaying as expected. Can anyone provide guidance on what might be going wrong ...

Use asyncData to access vuex in data layer

When encountering the error "id is undefined", how can one access a Vuex property within the data object? asyncData({ store }) { let id = store.state.auth.id return { id } }, data: () => ({ items: [ { title: 'Profile&ap ...