2

I see this bug in console:

[Vue warn]: Property or method "product" 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.

My template id="productDetail" not receive the property "product" of the template id="product" I don't know how I can push this, please see my cod.

HTML LIST That's ok when I click the router-link the url change to:

/product/iphone-x-64-gb for example.

<template id="product" functional>
<div class="wrapper">
    <ul class="row">
        <li v-for="(product, index) in products" class="col l4 m6 s12">
            <div class="card-box">
                <div class="card-image">
                    <img :src="product.images" :alt="product.images" class="responsive-img"/>
                </div>
                <div class="card-content">
                    <h3><a href="#">{{ product.brand }}</a></h3>
                    <span class="price-used"><i class="used">{{ index }} gebrauchte Roomba 651</i></span>
                </div>
                <div class="card-action row">
                    <span class="col s6 price"><span>{{ product.price }}</span>
                </div>
                <div>
                    <router-link class="btn btn-default light-green darken-3" :to="{name: 'product', params: {product_id: product.id}}">meer detail</router-link>
                </div>
            </div>
        </li>
    </ul>
</div>

HTML PRODUCT DETAIL (THAT NO RECEIVE THE "product")

<template id="productDetail" functional>
<div class="row">
    <div class="col s12 m6">
        <img src="images/iphone-8-64-gb.jpg" alt="product.images" class="responsive-img"/>
    </div>
    <div class="col s12 m6">
        <h3>{{ product.title }}</h3>
        <h5>{{ product.price }}<h5>
        <div class="col s12 m6">
            <a class="waves-effect waves-light btn light-green darken-3"><i class="material-icons left">add_shopping_cart</i>kopen</a>
        </div>
        <div class="col s12 m6">
            <router-link class="btn btn-default light-green darken-3" :to="{path: '/'}">
                <span class="glyphicon glyphicon-plus"></span><i class="material-icons left">arrow_back</i>terug
            </router-link>
        </div>
    </div>
</div>

THE .JS

var List = Vue.extend(
{
    template: '#product',
    data: function ()
    {
        return {products: [],};
    },
    created: function()
    {
        this.$http.get('https://api.myjson.com/bins/17528x').then(function(response) {
            this.products = response.body.products;
        }.bind(this));
    },

});

const Product =
{
    props: ['product_id'],
    template: '#productDetail'
}

var router = new VueRouter(
{
    routes: [
    {path: '/', component: List},
    {path: '/product/:product_id', component: Product, name: 'product'},
    ]
});


var app = new Vue(
{
    el: '#app',
    router: router,
    template: '<router-view></router-view>'
});

Thank for your help.

0

2 Answers 2

1

Your props should be props: ['product'] instead of props: ['product_id']


<parent-component :product="product"></parent-component>

ChildComponent.vue

export default {
  name: 'child-component',
  props: ['product']
}
Sign up to request clarification or add additional context in comments.

5 Comments

Very nice is correct, but now I need defined the "title" ofthe <h3>{{ product.title }}</h3> mmmmm...
[Vue warn]: Error in render: "TypeError: Cannot read property 'title' of undefined"
Bind your product using v-bind:product="product" on the child component tag
I can try, but dont understand here... sorry
Would you like to close the issue by accepting an answer?
1

First activate props on the route:

var router = new VueRouter({
...
      path: '/product/:product_id',
      component: Product,
      name: 'product',
      props: true                    // <======= add this line
    },
...

Now the product_id will be set on the Product component.

So, you want to display the whole product information, but at this moment you only have the product_id. The solution is to fetch the product:

const Product = {
  props: ['product_id'],
  template: '#productDetail',
  data: function() {                              // <============ Added from this line...
    return {
      product: {}     // add {} so no error is thrown while the product is being fetched
    };
  },
  created: function() {
    var productId = this.product_id;
    // if there is a URL that fetches a given product by ID, it would be better than this
    this.$http.get('https://api.myjson.com/bins/17528x').then(function(response) {
      this.product = response.body.products.find(function (product) { return product.id == productId });
    }.bind(this));
  }                                               // <============ ...to this line.
}

Check JSFiddle demo here of the solution above.


Alternative solution: passing the whole product as prop

Pass the product in the params: (along with product_id):

<router-link class="btn btn-default light-green darken-3" :to="{name: 'product', 
             params: {product_id: product.id, product: product}}">meer detail</router-link>
                                            ^^^^^^^^^^^^^^^^^^

Activate props on the route:

var router = new VueRouter({
...
      path: '/product/:product_id',
      component: Product,
      name: 'product',
      props: true                    // <======= add this line
    },
...

Finally, add product so you can use it:

const Product = {
  props: ['product_id', 'product'],         // <======= added 'product' here
  template: '#productDetail'
}

Demo JSFiddle for this solution here.

1 Comment

Nice, nice, nice, your great! Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.