Fabricio Sobral
Fabricio Sobral

Reputation: 41

Why my v-for doesn't loop? VUE.JS with JSON

I'm loading the data coming from a .json but the v-for does not return a loop.

MY HTML:

<div id="app">
    <template v-for="product in products">
        <p>{{ product.brand }}</p>
        <p>{{ product.images }}</p>
        <p>{{ product.id }}</p>
        <p>{{ product.title }}</p>
        <p>{{ product.description }}</p>
        <p>{{ product.price }}</p>
    </template>

</div>

MY JS:

new Vue({
el: '#app',
data: {
    products: []

},
methods: {

},
created: function() {
    var self = this;
    self.$http.get('http://localhost/app/products.json').then(function(response) {
        self.products = response.body;
    });
}
});

MY JSON:

"product": [
    {
        "brand": "Apple",
        "images":"images/iphone-x-64-gb.jpg",
        "id": "iphone-x-64-gb",
        "title": "iPhone X 64 GB",
        "description": "Lorem ipsum dolor",
        "price": "1.159,00"
    },
    {
        "brand": "Apple",
        "images":"images/iphone-x-256-gb.jpg",
        "id": "iphone-x-256-gb",
        "title": "iPhone X 256 GB",
        "description": "Lorem ipsum dolor",
        "price": "1.329,00"
    },
    {
        "brand": "Apple",
        "images":"images/iphone-8-64-gb.jpg",
        "id": "iphone-8-64-gb",
        "title": "iPhone 8 64 GB",
        "description": "Lorem ipsum dolor.",
        "price": "819,99"
    }
   ]
  }

if I write in HTML like this dosen't work but if I put

{{ product[3].brand }}

for example ... I can see only this one, just loop dosen't working.

Upvotes: 1

Views: 3636

Answers (1)

skribe
skribe

Reputation: 3615

Change your template to be something like the following...

<template>
    <div class="wrapper">
        <div  v-for="product in products">
              <p>{{ product.brand }}</p>
              <p>{{ product.images }}</p>
              <p>{{ product.id }}</p>
              <p>{{ product.title }}</p>
              <p>{{ product.description }}</p>
              <p>{{ product.price }}</p>
        </div>  
    </div>
</template>

Vue templates require a single root element between the <template> tags and also I believe v-for won't work properly on root element so I am nesting that in a "wrapper."

If you look in your dev tools console you probably will see an error that says something like.

Cannot use v-for on stateful component root element because it 
renders multiple elements.

or

[Vue warn]: Multiple root nodes returned from render function. 
Render function should return a single root node.

Additional


Also it appears you may have some other issues with your code. It seems to me your request should be like the following unless I am missing something about the way your json is being returned.

created: function() {
   this.$http.get('http://localhost/app/products.json').then(function(response) {
   this.products = response.body.products;
}.bind(this));

},

Notice the change from response.body to response.body.products Also it is fine to assign self to this but I find using .bind(this) more succinct.

Here is a working fiddle based on your code. https://jsfiddle.net/skribe/umx98rxm/

Upvotes: 3

Related Questions