Getting around prop immutability in Vue.js
Tags: javascript, vue, webdev, beginners
Published: 2021-10-20 14:40:39


_This article is for beginner and intermediate developers who have problems wrapping their head around why props are immutable and also why you cant just go ahead and edit it without actually having console errors._

## The problem
Let say you have a component, in that component there is a method that calls an alert and if the alert is confirmed, then an index is found and then splice is done.
```javascript
//ChildComponent.vue
export default{
 props: {
    skillsToMerge: {
      required: true,
      type: Array,
      default: () => []
    }
  },
 methods: {
  onRemoveSkill(skill) {
    const confirmRemoval = window.confirm(`Proceed to remove ${skill.name}?`);
    if (confirmRemoval) {
      const index = this.skillsToMerge.findIndex((s) => s.id === skill.id);
      this.skillsToMerge.splice(index, 1);
      }
    },
  }
}
 ```
In any other situation, this would have been a perfectly fine activity, but when it comes to vue.js props this will throw a warning in the console, and if you are using ESlint it will highlight that line as an error

![linting error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aee6mqknme7j4j6bahmr.png)

## Why is this a problem? 
Immutability for props means it never changes or should not be changed
Props originate from a single data source, that is why it is by default reactive which means that every action taken on the original data source will affect every other child using that data source or prop, now imagine that your data could be changed midway, it wouldn't make for a very reliable data reference. If every component that used the data was able to edit it error fixing would be a tedious task.

## Solution
Think of props are that data you can copy and read but cant edit, or an article on [dev.to](https://dev.to) that someone has written, you could read it, and copy and even share it but you cant edit the post, only the author can. Therefore props should only be edited in the pages or components where they originate from. In other words you can only edit it when it is a data variable and not a prop

This gives us 2 ways of going of editing our props without effectively breaking its immutability

### Solution 1: Emitters
Emitters are a way for child components to trigger an action in the parent, they are created by using
```javascript 
this.$emit('myEvent')
```
then it the parent do this on the child
```javascript 
<child-component v-on:myEvent="doSomething"></child-component>
```
This will ensure that you can trigger a function in the parent on the data variable without directly editing props

### Solution 2: functions
Functions or methods are one of the most useful syntaxes in code, and when you realize that functions could be used as props it effectively opens up unlimited possibilities. Lets look at the code below
 
```javascript
//ChildComponent.vue
export default{
 name: 'ChildComponent',
 props: {
    skillsToMerge: {
      required: true,
      type: Array,
      default: () => []
    },
   mergeSkills: {
      type: Function,
      default: () => {},
    },
  },
 methods: {
  onRemoveSkill(skill) {
    const confirmRemoval = window.confirm(`Proceed to remove ${skill.name}?`);
    if (confirmRemoval) {
        this.mergeSkills(skill);
    },
  }
}
 ```
 
```javascript
//ParentComponent.vue
export default {
name: 'ParentComponent',
data(){
 return {
 skillsToMerge: [],
 }
}
methods: {
 mergeSkills(skill) {
      const index = this.skillsToMerge.findIndex((s) => s.id === skill.id);
      this.skillsToMerge.splice(index, 1);
    },
}

}
```
Lets explain what is happening in the code above, instead of trying to splice the `skillsToMerge` prop we create a function inside the parent component where the `skillsToMerge` variable was created and edit it there

The reason it is better to do it this way is that
1. It protects your prop by allowing only that function to edit your data outside the parent component. This is quite similar to having private variables.
2. It makes code refactoring easier since editing the logic of the `mergeSkills` function in the parent component affects every component it is used in.
3. If there are a lot of nested child components, emitting events upwards will take much more code to do and it will be quite easy to have an error.
4. Finally when using inject-provide using methods becomes so much easier as there isn't a need to pushed events upwards and also methods don't need the reactivity that  props do, hence it will make your code cleaner

## Conclusion
There are surely more ways to deal with the limitations imposed by props due to its immutability but that limitations is also its greatest benefit due to the security it provides as a single source of data. 
This method logic is taken from how Vuex manipulates state using actions, keeping that in mind will make the benefits clearer.

> I hope this has benefited you. Until next time, happy coding