Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kendrick's avatar

[Vue warn]: data functions should return an object

A User hasMany Card.php, within my first Component I am fetching all cards, to loop through them within my second Component, where I am getting the card prop, with the possibility to delete the card (below)

This is the CardComponent

<template>
  <div> 
    <div>   
      <div>
        <p>{{card.name}}</p> 
        <button @click="deleteCard(card.id)" class="button" v-model="card">-</button>
      </div>  
    </div>  
  </div>
</template>

<script>

export default { 

  props: ['card'],

  data() {   
    
  },

  methods: {

    deleteCard(cardId) {
      const self = this; 
        axios.delete('/cards/' + cardId)
        .then((response) => {
          self.removeCard(cardId);
        }).catch((response) => {
          console.log(response);
        }); 
    },

    removeCard(cardId) {
      this.cards = _.remove(this.cards, (card) => { return card.id != cardId });  
    }
  },

};

</script>

I am currently receiving this console error for fetching all Cards: Property or method "card" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

If I trigger the deleteCard method, I get: TypeError: target.$data is not an Object. (evaluating 'key in target.$data')

Any obvious mistakes within Vue?

0 likes
18 replies
ahmeddabak's avatar
Level 47

On child components your data property should be a function that returns an object, like this

data () {
    return {
        //data here
    },
)
1 like
ahmeddabak's avatar

You do not have a card object inside the component data, i think you should fetch the card from server and then store it in the component data using axios

data () {
    return {
        card : {
            name : 'Foo'
        }
    },
)
kendrick's avatar

This will return The data property "card" is already declared as a prop. Use prop default value instead.

ahmeddabak's avatar

remove v-model="card" on the button, and you do not need a card object inside the data object, so remove this too if you added it from my last reply

card : {
            name : 'Foo'
        }
kendrick's avatar

Thank you, this one solved some of the errors. @ahmeddabak

// removed v-model="card"

data () {
     return {
       
    }
}

Now I am left with Property or method "card" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

kendrick's avatar

CardListComponent.vue

<template>
    <div>      
        <div v-for="card in cards">   
          <card :card="card"></card> 
      </div>    
    </div>
</template>

<script>

export default { 

    props: ['user'],

    data() {
        return {
            cards: [],  
        }
    },
    
    created() { 
        if (!this.cards.length) {
            this.fetchCards();
        } 
     },

     methods: {
       fetchCards(){
           axios.get('/api/cards/' + this.user.id).then(response => this.cards = response.data.data);
       }
    }  

};
</script>
ahmeddabak's avatar

Try re-compiling your js code and clearing the cache

kendrick's avatar

Unfortunately, still getting this one, somehow four times Property or method "card" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

Also by removing v-model="card", from the button, the button will not be triggered, anymore.

ahmeddabak's avatar

I have tested the code and it is working correctly, check where you are importing the CardComponent component, i believe you might be importing the wrong file.

After you check the import, you will still have the problem with the removeCard method, it is in the card component, when it should be on the cardlist component

kendrick's avatar

Thank you for the testing @ahmeddabak

How does the data(){} look like within your CardComponent? I had a duplicate component name within my app.js file, handled it, but still receiving,

Property or method "card" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

after an npm run dev.

CardComponent:

props: ['card'],

  data() {   
    return {
       
    }
  },

  methods: {

    deleteCard(cardId) {
      const self = this; 
        axios.delete('/cards/' + cardId)
        .then((response) => {
          self.removeCard(cardId);
        }).catch((response) => {
          console.log(response);
        }); 
    },
    
  },

CardListComponent

 methods: {
       fetchCards(){
           axios.get('/api/cards/' + this.user.id).then(response => this.cards = response.data.data);
       },

       removeCard(cardId) {
         this.cards = _.remove(this.cards, (card) => { return card.id != cardId });  
       }
    }  
ahmeddabak's avatar

This is my CardComponent

<template>
  <div> 
    <div>   
      <div>
        <p>{{card.name}}</p> 
        <button @click="deleteCard(card.id)" class="button">-</button>
      </div>  
    </div>  
  </div>
</template>

<script>

export default { 

  props: ['card'],

  data() {   
    return {}
  },

  methods: {

    deleteCard(cardId) {
      const self = this; 
        axios.delete('/cards/' + cardId)
        .then((response) => {
          self.removeCard(cardId);
        }).catch((response) => {
          console.log(response);
        }); 
    },
  },

};

</script>
ahmeddabak's avatar

And this is my CardListComponent

<template>
    <div>      
        <div v-for="card in cards">   
          <card :card="card"></card> 
      </div>    
    </div>
</template>

<script>
export default { 

    props: ['user'],

    data() {
        return {
            cards: [],  
        }
    },
    
    created() { 
        if (!this.cards.length) {
            this.fetchCards();
        } 
     },

     methods: {
       fetchCards(){
           axios.get('/api/cards/' + this.user.id).then(response => this.cards = response.data.data);
       }
    }  

};
</script>
kendrick's avatar

Thank you @ahmeddabak

The errors are gone, I had referenced to a v-model="card" within my view, which triggered the error.

I can't trigger the deleteCard method, currently. Any suggestions on how to solve it?

ahmeddabak's avatar

to cal ldeleteCard you do not need the v-model directive. you just need @click="deleteCard(card.id)" then you need to send a message to the parent component, to tell it that the card is deleted, and it can remove it from the view

1 like
kendrick's avatar

deleteCard() will be triggered, but the Card won't be removed from the CardListComponent.

How can I send a message to the CardListComponent? Because I tried to move removeCard

removeCard(cardId) {
         this.cards = _.remove(this.cards, (card) => { return card.id != cardId });  
       }

to the parent component, as it uses this.cards, but it won't be triggered.

ahmeddabak's avatar

inside CardComponent you should emit an event

deleteCard(cardId) {
      const self = this; 
        axios.delete('/cards/' + cardId)
        .then((response) => {
        self.$emit('removed', cardId); //fire an event called removed
        }).catch((response) => {
          console.log(response);
        }); 
    },

the on you CardListComponent you can listen to the removed event and when fired call the removeCard method

<card :card="card" @removed="removeCard"></card> 
1 like

Please or to participate in this conversation.