Codementor Events

The better way to Validate the props in Vue

Published Apr 20, 2020Last updated Oct 16, 2020

Original Post Dev.to

Well, Whenever we communicate with data, we need to validate the data in order to achieve the expected behavior and these apply to any type of communication that happens within the application and when it comes to communicating from Parent to Child using props is no exception.

Let's dig into props in detail to write better and predictable code.

First, let's define the parent component which is responsible to pass the data to the child.

Parent component<a name=parent-component"></a>

Parent component consists of the movies list which basically passes the list of the movies to the child component. For better understanding will pass static props to more focus on how to write props better.


<MovieList name="Movie 1" image="assets/images/movie-1.png" rating="7.5" 
watchlist="true">

Array syntax <a name="chapter-1"></a>

Using array syntax, props can be directly passed using the name of the props and that will be used to display the data in the template.


export default {
  name: 'MovieList',
  props: ['name', 'image', 'rating', 'watchlist']
}

Basically, It can be helpful for prototyping of the app but for big and scalable this approach is not enough to make code more scalable and reliable. Below are lists of disadvantages of using this syntax.

Cons

  • No Type checking
  • No Information indicates on mandatory and optional props
  • No Default value
  • No Appropriate custom validator

Well, All the shortcomings discussed above will be handled in the below examples to make our code more predictable.

Object syntax <a name="chapter-2"></a>

Alternate to Array syntax, props can also be defined with object syntax and this syntax can facilitate us to use three key properties with prop attributes which helps us to write better code.

  1. type checks the data type of prop.
  2. required indicates whether the prop is required or not.
  3. default indicates the value of prop if the parent component failed to pass that prop.

export default {
  name: "MovieList",
  props: {
    name: {
      type: String,
      required: true
    },
    rating: {
      type: [Number, String],
      required: false,
      default: 5
    },
    wishlist: {
      type: Boolean,
      default: false
    },
    image: {
      type: String,
      default: require("@/assets/default-poster.png")
    }
  }
};

Below are the things which we can notice from the above code.

  • Props are now supporting types. The list of available types includes some of the JavaScript data types & others are as below.

    • String
    • Number
    • Object
    • Array
    • Boolean
    • Date
    • Function
    • Symbol
  • A prop can accept multiple data types as used in the rating prop.

  • Required props can be easily identified.

  • The default value is used in a case where the parent failed to pass the prop.

  • If default property is set, the required properties become true automatically hence even not writing would make sense. ( e.g. wishlist & image prop)

So, The prop with object syntax is much better than the array syntax as it overcomes a lot of cons that come with object syntax, which we discussed above. but still, there is a catch in code with the image prop.

Imagine, the Parent component somehow passed the image URL wrong.

<Movie-List name="Movie with incorrect image path" image="../assets/default.png"/>

In order to handle such cases, prop with object syntax have another property called validator to validate the incoming prop and if our requirement for the prop doesn't match, it throws an error. Thus, it helps to write more reliable and scalable code. Let's go through the example below

Object syntax with custom validator <a name="chapter-3"></a>


export default {
  props: {
    image: {
      type: String,
      default: require("@/assets/default-poster.png"),
      validator: propValue => {
        const hasImagesDir = propValue.indexOf("@/assets/") > -1;
        const listOfAvailableExt = [".jpeg", ".jpg", ".png"];
        const isValidExt = listOfAvailableExt.some(ext =>
          propValue.endsWith(ext)
        );
        return hasImagesDir && isValidExt;
      }
    }
  }
}

Here, the validator function accepts a prop value and if the value passes the given validations, then the prop image is visible otherwise it will throw an error in the console as below.

[Vue warn]: Invalid prop: custom validator check failed for prop "image".

Now, we can simply correct the path of the image which renders the correct image.

Here is the working codesandbox

{% codesandbox j5ss7 %}

NOTE: The props are validated before the component instance is created, hence the instance properties such as data, computed, etc will not be available to use inside default or validator function.

I hope it helps to write better code.🤞

Feel free to post any questions 📝 on the comments below. I would be more than happy to answer them.

Discover and read more posts from Varit J Patel
get started
post comments3Replies
Harshad Satra
4 years ago

Is it possible to set default value, if the custom validation fails?

Varit J Patel
4 years ago

Yes. That is what the in the last example of image I have did it. You can refer the attached codesanbox.

Harshad Satra
4 years ago

Yes, I saw the Codesandbox, It just gives warning in the Console, but the image source is still using the incorrect path.

I am asking, if there is a way to update the Incorrect path with Default Prop value?