Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

My view is like this :

<div class="panel panel-default panel-store-info">
    ...
    <div id="app">
        <AddFavoriteProduct></AddFavoriteProduct>
    </div>
    ....
</div>

My component is like this :

<template>
    <a href="javascript:" class="btn btn-block btn-success" @click="addFavoriteProduct({{ $product->id }})">
        <span class="fa fa-heart"></span>&nbsp;Favorite
    </a>
</template>

<script>
    export default{
        name: 'AddFavoriteProduct',
        props:['idProduct'],
        methods:{
            addFavoriteProduct(event){
                event.target.disabled = true
                const payload= {id_product: this.idProduct}
                this.$store.dispatch('addFavoriteProduct', payload)
                setTimeout(function () {
                    location.reload(true)
                }, 1500);
            }
        }
    }
</script>

When click button favorite, it will call controller on the laravel

I had register on the app.js like this :

...
import AddFavoriteProduct from './components/AddFavoriteProduct.vue';
...
components: {
                ...
                AddFavoriteProduct
            },
...

When executed, the button favorite does not appear.

Please help.

UPDATE

There exist error like this :

[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option. (found in root instance)

Whereas I had register it

share|improve this question
    
Are you using any other component or this is first component you are trying, also can you add whole of App.js if possible. which version of vue you are using – Saurabh 2 days ago
    
@Saurabh, Yes, I have another component. Another component works well – moses toh 2 days ago
up vote 2 down vote accepted

Three fixes that I can see...

First, omit name: 'AddFavoriteProduct' in your component (it's not required for single-file components) and use kebab-case for the component in your template. Second, you appear to be missing the id-product prop

<add-favorite-product :id-product="someProductIdFromSomewhere"></<add-favorite-product>

Third, you don't use interpolation in bound properties and you don't even need to pass anything other than the $event to your addFavoriteProduct method

@click="addFavoriteProduct($event)"
share|improve this answer
    
Great. Thanks. It works. But when click button favorite, there exist error : [vuex] unknown action type: addFavoriteProduct – moses toh 2 days ago
1  
@mosestoh The error says vuex can't find the action addFavoriteProduct. Have you declared / defined the action in your vuex store? – Donkarnash 2 days ago
    
@Donkarnash, Yes. the action in vuex store – moses toh 2 days ago
    
@mosestoh do you have other vuex actions working? – retrograde yesterday

Are you getting any error?

One mistake I see in your code is, you are taking one parameter: event, while you are trying to pass {{ $product->id }} to it, which seems a laravel variable. (Sorry, I don't know laravel)

If you want both event and product->id in method, you have to pass both parameters from HTML, like it is in docs with help of $event

<template>
    <a href="javascript:" class="btn btn-block btn-success" @click="addFavoriteProduct({{ $product->id }},  $event)">
        <span class="fa fa-heart"></span>&nbsp;Favorite
    </a>
</template>

<script>
    export default{
        name: 'AddFavoriteProduct',  // I am not sure if name is needed, don't remember seeing it in docs
        props:['idProduct'],
        methods:{
            addFavoriteProduct(productId, event){
                event.target.disabled = true
                const payload= {id_product: this.idProduct}
                this.$store.dispatch('addFavoriteProduct', payload)
                setTimeout(function () {
                    location.reload(true)
                }, 1500);
            }
        }
    }
</script>

Another problem is you are expecting a prop idProduct, which is not being passed to component, You have to pass it like this in kebab-case:

<div class="panel panel-default panel-store-info">
    ...
    <div id="app">
        <AddFavoriteProduct id-product="4"></AddFavoriteProduct>
    </div>
    ....
</div>
share|improve this answer

HTML is case-insensitive, so your custom button element <AddFavoriteProduct></AddFavoriteProduct> is being interpreted as your Vue warning reports: <addfavoriteproduct>

When you name your component with camelCase or PascalCase, the corresponding tag name you should be using in your markup should be kebab-cased like so: <add-favorite-product></add-favorite-product>

Vue knows to do the conversion from "dash-letter" to "uppercase-letter".

share|improve this answer

I am not used to vuex, as I generally implement my own store as a POJO object - not graduated with the learning curve of vuex. So can't provide a working solution with vuex, however to my knowledge, you need to kind of import the action(s) in your component - you can try the below

<template>
<a href="javascript:" class="btn btn-block btn-success" @click="addFavoriteProduct({{ $product->id }},  $event)">
    <span class="fa fa-heart"></span>&nbsp;Favorite
</a>
</template>

<script>
    export default{
        props:['idProduct'],
        vuex: {
            actions: {
                setFavoriteProduct: setFavoriteProduct
                // assuming you named the action as setFavoriteProduct in vuex
                // avoid duplicate naming for easy debugging
            }
        }
        methods:{
            addFavoriteProduct(productId, event){
                event.target.disabled = true
                const payload= {id_product: this.idProduct}
                // this.$store.dispatch('addFavoriteProduct', payload)
                this.setFavoriteProduct(payload);
                setTimeout(function () {
                    location.reload(true)
                }, 1500);
            }
        },
    }

Note: From Vuex2 the store.dispatch() accepts only one argument (not a problem with your current use case), however if you need to pass multiple arguments to your action you can work around like

store.dispatch('setSplitData',[data[0], data [1]])

// in the action:
setSplitData (context, [data1, data2]) { // uses ES6 argument destructuring

    OR

//... with an object:
store.dispatch('setSplitData',{ 
  data1: data[0], 
  data2: data [1],
})

// in the action:
setSplitData (context, { data1, data2 }) { // uses ES6 argument destructuring
//source: LinusBorg's comment at https://github.com/vuejs/vuex/issues/366
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.