Razvan Zamfir
Razvan Zamfir

Reputation: 4614

What causes the type check failed for prop error in this Vue 3 application?

I am working on a small Todo App with Vue 3. In App.vue I have the 3 child components:

<template>
  <div id="app">
    <Header 
    title="My todo list" 
    :unsolvedTodos = []
    />

    <List 
      :todos="todos"
      dataIsLoaded=false 
      @delete-todo="deleteTodo" 
      @toggle-todo="toggleTodo" />

    <Footer
      :isValidInput = true
      newTitle = ""
      placeholder="+ Add new todo"
      validationMsg = "Please add at least 3 characters"
      @add-todo="addTodo"
      />

  </div>
</template>

<script>
import axios from 'axios'
import Header from './components/Header.vue'
import List from './components/List.vue'
import Footer from './components/Footer.vue'

export default {
  name: 'App',
  components: {
    Header,
    List,
    Footer
  },
  // More code
}

</script>

In the List.vue component I have:

<template>
  <ul class="todo-list" v-if=dataIsLoaded>
      <TodoItem v-for="todo in todos.slice().reverse()"
        :key="todo.id" 
        :class="{done: todo.completed}" 
        :todo="todo" 
        @delete-todo="$emit('delete-todo', todo.id)"
        @toggle-todo="$emit('toggle-todo', todo)"
        />
    </ul>
    <div class="loader" v-else></div>   
</template>

<script>
import TodoItem from "./TodoItem.vue";

export default {
  name: 'List',

  components: {
    TodoItem,
  },

  props: {
    dataIsLoaded: Boolean,
    todos: Array
  },

  emits: ['delete-todo', 'toggle-todo']
}
</script>

The problem

As can be seen above, I have explicitly set dataIsLoaded to a boolean.

Yet, in the console, I get the error:

Invalid prop: type check failed for prop "dataIsLoaded". Expected Boolean, got String with value "false".

What am I missing?

Upvotes: 2

Views: 771

Answers (2)

Xunita
Xunita

Reputation: 69

Use :dataIsLoaded="false" instead of dataIsLoaded="false" wich expects a string by default.

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28404

You can bind it to parse the value to a boolean:

const list = Vue.component('list', { template: "#list", props: { dataisloaded: Boolean } });

new Vue({ el: "#app", components: { list } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<template id="list">
  <div>{{dataisloaded}}</div>
</template>

<div id="app">
  <list :dataisloaded=false />
</div>

EDIT: If you want to pass the value from the parent to the child component as a data variable:

const list = Vue.component('list', { template: "#list", props: { dataisloaded: Boolean } });

new Vue({ 
  el: "#app", 
  components: { list },
  data: () => ({
    dataisloaded: false
  }),
  mounted() {
    setTimeout(() => this.dataisloaded = true, 2000);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<template id="list">
  <div>{{dataisloaded}}</div>
</template>

<div id="app">
  <list :dataisloaded="dataisloaded" />
</div>

Upvotes: 1

Related Questions