Art Ekipa
Art Ekipa

Reputation: 5

How to get nested JSON data in vue.js

I have a JSON file like this, and this is 'pproduct' array

[
        {
        "id": 2,
        "title": "Domena .pl, com.pl lub .eu 0 z\u0142 przez pierwszy rok.",
        "slug": "domena-pl-0zl-1rok",
        "pubickdate": "2018-08-20",
        "price": 150,
        "mainphoto": null,
        "pcontent": null,
        "created_at": "2018-08-20 10:14:42",
        "updated_at": "2018-08-20 10:14:42",
        "deleted_at": null,
        "pcategories": [
            {
                "id": 1,
                "pcategoryname": "Pakiet internetowy",
                "pcslug": "pakiet-internetowy",
                "created_at": "2018-08-20 10:04:41",
                "updated_at": "2018-08-20 10:04:41",
                "deleted_at": null,
                "pivot": {
                    "pproduct_id": 2,
                    "pcategory_id": 1
                }
            }
        ]
    },
    {
        "id": 1,
        "title": "Indywidualny projekt serwisu spe\u0142niaj\u0105cy wymagania User Center Design dostosowany do bran\u017cy firmy",
        "slug": "indywidualny-projekt-serwisu",
        "pubickdate": "2018-08-20",
        "price": 600,
        "mainphoto": null,
        "pcontent": null,
        "created_at": "2018-08-20 10:11:04",
        "updated_at": "2018-08-23 07:02:05",
        "deleted_at": null,
        "pcategories": [
            {
                "id": 1,
                "pcategoryname": "Pakiet internetowy",
                "pcslug": "pakiet-internetowy",
                "created_at": "2018-08-20 10:04:41",
                "updated_at": "2018-08-20 10:04:41",
                "deleted_at": null,
                "pivot": {
                    "pproduct_id": 1,
                    "pcategory_id": 1
                }
            }
        ]
    }
]

How to get nested data like: pcategoryname, pcslug in vue.js. Any suggestions on how to display this data in the v-for loop. I would like to display: title, price, pcategoryname, pcslug.

When I use {{ pproduct.pcategoryname }} I get 'undefined' error.

Here is my vue.js template

<template>
    <div class="listproduct">
        <div class="container col s12 m8 offset-m2 l6 offset-l3">
            <h2>Pakiet Internetowy</h2>  
            <div class="list">                
                <ul>
                   <li v-for="pproduct in pproducts" :key="pproduct.id">
                       <!-- <span>{{ index + 1 }}.</span> -->
                       <span>{{ pproduct.title }}</span>     
                       <span><strong>Kategoria: {{ pproduct.pcategoryname }}</strong></span>
                       <span class="price">{{ pproduct.price }} zł</span>
                   </li>
                </ul>
            </div>       
        </div>
    </div>
</template>

<script>
export default {
    data: function(){
        return {
           pproducts: [],
           pcategories: []
        };
    },

    methods: {
        filteredPproducts: function(){
            if(this.pproducts.length){
                 return this.pproducts;
            };
            // if(this.pcategories.length){
            //      return this.pcategories;
            // };

        }
    },

    created(){
        axios.get('http://127.0.0.1:8000/api/pproducts')
        .then(response => {
            console.log(response.data)
            console.log(response.data.pcategoryname)
            this.pproducts = response.data,
            this.pcategories = response.data                    

        })
    }
}
</script>

<style>
span.price{
    font-weight: bold;
    color: #ef6c00;
}

</style>

Upvotes: 0

Views: 6445

Answers (2)

Daniel
Daniel

Reputation: 35724

note that your categoryname is an array that you you need to loop through. if you know that you'll only have one, you can use {{product.pcategories[0].pcategoryname}}, however this will cause issues if you have not categories, and will only show one even when there are more

here are two options of dealing with this

Option 1 - use v-for to loop through categories and add dom element for each

<li v-for="pproduct in pproducts" :key="pproduct.id">
    <span>{{ pproduct.title }}</span>     
    <span><strong>Kategoria: </strong><strong v-for="pcategory in product.pcategories" :key="pcategory.id">{{ pcategory.pcategoryname }}</strong></span>
    <span class="price">{{ pproduct.price }} zł</span>
</li>

Option 2 - extract the name only for all categories using a map().join(), this will return a String that you can display.

<li v-for="pproduct in pproducts" :key="pproduct.id">
    <span>{{ pproduct.title }}</span>     
    <span><strong>Kategoria: {{ product.pcategories.map(c=>c.pcategoryname).join(', ') }}</strong></span>
    <span class="price">{{ pproduct.price }} zł</span>
</li>

Upvotes: 0

Ricky Ruiz
Ricky Ruiz

Reputation: 26791

You have an array of categories in your product object and you are trying to access them using pproduct.pcategoryname, pcategoryname is a property of a category not a product.

Iterate over the categories of a product too.

new Vue({
  el: "#app",

  data() {
    return {
      pproducts: [{
          id: 2,
          title: 'Domena .pl, com.pl lub .eu 0 z\u0142 przez pierwszy rok.',
          slug: 'domena-pl-0zl-1rok',
          pubickdate: '2018-08-20',
          price: 150,
          mainphoto: null,
          pcontent: null,
          created_at: '2018-08-20 10:14:42',
          updated_at: '2018-08-20 10:14:42',
          deleted_at: null,
          pcategories: [{
            id: 1,
            pcategoryname: 'Pakiet internetowy',
            pcslug: 'pakiet-internetowy',
            created_at: '2018-08-20 10:04:41',
            updated_at: '2018-08-20 10:04:41',
            deleted_at: null,
            pivot: {
              pproduct_id: 2,
              pcategory_id: 1,
            },
          }, ],
        },
        {
          id: 1,
          title: 'Indywidualny projekt serwisu spe\u0142niaj\u0105cy wymagania User Center Design dostosowany do bran\u017cy firmy',
          slug: 'indywidualny-projekt-serwisu',
          pubickdate: '2018-08-20',
          price: 600,
          mainphoto: null,
          pcontent: null,
          created_at: '2018-08-20 10:11:04',
          updated_at: '2018-08-23 07:02:05',
          deleted_at: null,
          pcategories: [{
            id: 1,
            pcategoryname: 'Pakiet internetowy',
            pcslug: 'pakiet-internetowy',
            created_at: '2018-08-20 10:04:41',
            updated_at: '2018-08-20 10:04:41',
            deleted_at: null,
            pivot: {
              pproduct_id: 1,
              pcategory_id: 1,
            },
          }, ],
        },
      ],
    }
  },
})

Vue.config.productionTip = Vue.config.devtools = false
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <h2>Products:</h2>
  <ol>
    <li v-for="product in pproducts" :key="product.id">
      <p>
        Product: {{ product.title }}
      </p>
      <p>
        Categories:
      </p>
      <ul>
        <li v-for="category in product.pcategories" :key="category.id">
          <p>
            {{ category.pcategoryname }}
          </p>
        </li>
      </ul>
    </li>
  </ol>
</div>

Upvotes: 1

Related Questions