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

Display the div only when the radio button has been selected

I have been attempting to tackle this issue for quite some time now, but unfortunately, I haven't had any success. My goal is to display a specific div on the webpage when a particular radio button is selected. While I have managed to achieve this by ...

How can we avoid re-rendering the same component repeatedly when using React Router v6?

As a beginner in react, I'm facing an issue with preventing components from re-rendering when navigating to a different page. Specifically, I want to display only text on my Signup and Login pages, but the Navbar keeps re-rendering every time I switch ...

Guide on incorporating the ":gt" filter from sizzle into vanilla javascript

I am currently working on adapting a jQuery plugin to be compatible with the AngularJS JQlite API, but I have encountered some challenges along the way. Here is an overview of the plugin: (function (e) { var $product = $('#product'), ...

Error: Unable to access attributes of an unspecified element (viewing 'category') in eval function ... in arranging elements in Array

Hey team, I'm in need of some assistance with a Vue error I've encountered. Being new to Vue, I'm struggling to pinpoint the cause of this issue. I'm currently working on creating a data table in Vue and attempting to implement data sor ...

Running cy.task after all test suites can be done by adding the task in a

I need some guidance on running cy.task after executing all test suites. I have a file generated at the start of the tests that I would like to remove once they are completed. Regardless of whether any tests passed or failed, I want to trigger cy.task im ...

Encountering difficulty accessing the router during testing in Next.js

Hello, I'm currently attempting to test a scenario where when a button is pressed, it should redirect to '/'. Normally this works fine, but during testing it fails and shows the following error: Cannot read properties of null (reading ' ...

Despite being installed, the message 'concurrently: command not found' pops up

I'm attempting to run two scripts simultaneously, and I came across the concurrently package that is supposed to assist with this. After executing npm install concurrently --save and verifying it in my package.json, I faced an issue when trying to run ...

Having trouble passing arguments to button methods in jasmine when applying vue and moment libraries

I am working on unit testing a Vue app using `jasmine` and `karma`. Here is an example of the code inside one of my components: After fetching data from a database with `v-for=(data,index)`, I am displaying the `data.date` in the template: <p class=&qu ...

Putting a Pause on CSS Transition using jQuery

I am attempting to delay a CSS transition for an element by using a delay function, with an additional 0.2s applied to make it slide 0.2s later than the initial delay of the main wrapper. I am applying a class to give it a transition effect to slide from r ...

NextJS application failing to display SVG icon in the absence of internet connection

https://i.stack.imgur.com/M9reE.jpg https://i.stack.imgur.com/Yyg4g.jpg Upon inspection of the provided images, it is evident that the src URL points to a location within the nextjs public folder. The issue arises when there is no internet connection - i ...

Determine in Jquery if all the elements in array 2 are being utilized by array 1

Can anyone help me figure out why my array1 has a different length than array2? I've been searching for hours trying to find the mistake in my code. If it's not related to that, could someone kindly point out where I went wrong? function contr ...

Is the new mui LoadingButton not available in the latest version?

According to the material UI documentation found at here, you are supposed to import LoadingButton from '@material-ui/lab/LoadingButton'; However, I am unable to locate this folder within mui/lab and the import statement is resulting in an erro ...

Is it necessary for a click handler to be triggered when clicking on a scrollbar?

Check out these HTML snippets: Jsfiddle <style> div { margin:20px; border: 30px red solid; padding: 20px; background-color:green; overflow-y:scroll; } </style> <div onclick="alert('div clicked');"> ...

Node.js request.url is returning incomplete URL

I am currently testing out the code snippet provided in a beginner's book on Node.js. var http = require("http"); var url = require("url"); function onRequest(request, response) { console.log("request URL is: " + request.url); var pathName ...

history.push() function is ineffective within a JavaScript file that does not contain a class

I've been delving into React and encountering an issue with the history.push("/dashboard") method, it's not functioning as expected. import axios from "axios"; import { GET_ERRORS, GET_PROJECT, GET_PROJECTS } from "./types"; export const createP ...

What is the correct way to update the state of an object in ReactJS using Redux?

Hello, I am facing an issue with storing input field values in the state object named 'userInfo'. Here is what my code looks like: <TextField onChange={this.handleUserUsername.bind(this)} value={this.props.userInfo.username} /> ...

Establishing connections in neo4j with the neo4j-nodejs API

I encountered an error while creating a relationship between two nodes that were generated within the code. Can someone advise me on the correct arguments for the function below and its proper formatting? node1.createRelationshipTo(node2, "some", {age:" ...

The processing time for this request is unreasonably long

My website is built using Laravel and Vue.js. I am facing an issue where a function takes more than 2 minutes to execute, resulting in the following error: 500 Internal Server Error Request Timeout This request takes too long to process and is timed out b ...

Exploring Angular 6 with Universal Karma for effective module testing

Issue I have been facing challenges while testing my Angular 6 application with Karma. I am encountering errors such as: Can't bind to 'ngModel' since it isn't a known property of 'mat-select'. Although the import works in ...

Jest test encounters an error due to an unexpected token, looking for a semicolon

I've been working on a Node project that utilizes Typescript and Jest. Here's the current project structure I have: https://i.stack.imgur.com/TFgdQ.png Along with this tsconfig.json file "compilerOptions": { "target": "ES2017", "modu ...