Print attributes of a JSON in VUEJS - javascript

I would like to read JSON data in my VueJS code.
Here my code :
<template>
{{info}}
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
info: null
};
},
mounted(){
axios
.get('data/products.json')
.then(response => (this.info = response.data.data)),
}
</script>
I have that on the website :
[ { "id": "1000", "code": "1", "name": "Certificats", "description":
"cert Description", "status": "ERROR"}, { "id": "1005", "code": "2",
"name": "Autre", "description": "Product Description", "status":
"ERROR"} ]
I would like to be able to call only for example info.id to print just the id or to use it like an attribute in a v-if or in a v-for.
For example be able to do something like that :
<div :v-for="number in info.id">
{{number}}
</div>
Do you know how to do it ?
Thanks

<div v-for="infoItem in info" :key="infoItem.id">
{{ infoItem.id }}
</div>
Another solution to show only the ids of the errors would be
<div v-for="infoItem in info" :key="infoItem.id">
<div v-if="infoItem.status === 'ERROR'"
{{ infoItem.id }}
</div>
</div>
It's bad practise to combine v-for and v-if in the same line.

I'd suggest you change your v-for loop, and reference whichever key you want to access
<div :v-for="item in info">
{{ item.id }}
{{ item.name }}
</div>
and so on.

Related

Vue.js cannot read property of null/undefined of nested object in Props

So i get an object from an axios call. I pass the object to a child element. Then in that child element i loop through the object to read a property of another nested object. and here i get the warning that the property i'm trying to read undefined/null. i did check the console and i'm receiving everthing properly the problem is in reading that nested property.
The Error
TypeError: Cannot read property 'username' of null
The object i receive looks like the following
{
"images": [
"1616575030315IMG-20210211-WA0003.jpg",
"1616575030316IMG-20210211-WA0004.jpg",
"1616575030316IMG-20210211-WA0000.jpg"
],
"_id": "605afa36320a772cecc4ed85",
"name": "Maman",
"brand": "Zara",
"user": {
"email": [
"zakisb97#gmail.com"
],
"_id": "6061bd38ada425383cc8a5b2",
"username": "zakisb97",
"tel": "0560728063",
"apropos": "salam123456",
},
"type": "Robes",
"size": "M",
"description": "Good to wear",
"price": "150",
}
Parent component: Market Products
<div
v-for="product in products"
class=""
:key="product.id"
>
<product-default :product="product" />
</div>
The product default child component
<h1>{{ product.user.username }}</h1> // results in undefined
export default {
props: {
product: {
type: Object,
require: true,
default: () => {}
},
},
data: () => ({
// nothing here
}),
}
You probably accessing object property while the object is undefined.
Try this:
<div
v-for="product in products"
class=""
:key="product.id"
>
<product-default v-if="product" :product="product" />
</div>
and this:
<h1 v-if="product && product.user">{{ product.user.username }}</h1>

Display nested Json in Angular component

I am new to angular. I am trying to display Json object in component. I am using keyvalue pipe with *ngFor to achieve this.
My Json Object
{
"categories": [
{
"categories": {
"id": 1,
"name": "Delivery"
}
},
{
"categories": {
"id": 2,
"name": "Dine-out"
}
},
{
"categories": {
"id": 3,
"name": "Nightlife"
}
},
{
"categories": {
"id": 4,
"name": "Catching-up"
}
},
{
"categories": {
"id": 5,
"name": "Takeaway"
}
}
]
}
My Component HTML:
<div *ngFor="let obcategories of users | keyvalue">
<div *ngFor="let obcategory of obcategories.value | keyvalue">
<div *ngFor="let nestedobcategory of obcategory.value | keyvalue">
{{nestedobcategory.value}}
</div>
</div>
</div>
It is displaying all both id value and name value. I want to display only name value.
Any help is much appreciated.
You can use {{nestedobcategory.value.name}} to access the name property:
<div *ngFor="let obcategories of users | keyvalue">
<div *ngFor="let obcategory of obcategories.value | keyvalue">
<div *ngFor="let nestedobcategory of obcategory.value | keyvalue">
{{nestedobcategory.value.name}}
</div>
</div>
</div>
Working Demo
Change:
{{ nestedobcategory.value }}
To:
{{ nestedobcategory.value.name }}
Code after changes:
<div *ngFor="let nestedobcategory of obcategory.value | keyvalue">
{{ nestedobcategory.value.name }}
</div>
Working Demo
A minor change would be:
nestedobcategory.value => nestedobcategory.value.name
IMP : In such cases use JsonPipe just to check what object you getting. If you use
{{ nestedobcategory.value | json }}
It will display your objects in the JSON Structure (Key/Value pair) and then you can access values that you want to display on the HTML.

Using an array's object's attribute in a v-for with v-bind in vue.js?

So I'm trying to follow what I've found in the API and examples from the vue.js page but it doesn't seem to be working out.
I have this component
Vue.component('project', {
data: function () {
return {
title: "Sketch",
desc: "Zoe Beauty is an online store web application that sells different types of makeup from many brands in " +
"the market. It works with a nodeJs server and Handlebars templating to create the front end. The app is " +
"created under the slogan “Just Shine”, Most feedback in the app is elusive to this slogan and so is it's " +
"graphic style. The user can filter the items by many different things such as a type of product, brand, price, " +
"rating, etc. Also, they can add items to their cart.",
links: [{
"github": {
"link": "https://github.com/booleanaVillegas/juliana-villegas-taller-uno",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/github.svg?alt=media&token=83edf83c-cd80-43fa-bedd-a2348ff23b3e"
},
"web": {
"link": "https://enigmatic-shelf-33047.herokuapp.com/",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/web.svg?alt=media&token=b5e092a2-beb3-4c72-a329-8e402e82032f"
}
}]
,
img: "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/projects%2Fzoe.png?alt=media&token=b0255dda-51f9-4958-8f7b-af978cc9b790"
}},
template: `
<div class="each-project">
<img src="https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/projects%2Fzoe.png?alt=media&token=b0255dda-51f9-4958-8f7b-af978cc9b790"
alt="" class="pic-project">
<h3 class="purple title-project">{{title}}</h3>
<p class="project-desc">{{desc}}</p>
<div class="links-container" v-for="link in links">
<a :href="link.link" class="link-container"><img
:src='link.logo' alt='link.key' class='link-img'></a>
</div>
</div>
`
});
The :src and :href in the v-for: link in links are not displaying anything, and when I inspect the element it is literally showing 'link.logo' instead of the actual link
how can I mix v-for and v-bind correctly?
first your array just contains 1 element, and that element was an object so just remove the []
links: {
"github": {
"link": "https://...",
"logo": "https://..."
},
"web": {
"link": "https://...",
"logo": "https://..."
}
}
look https://codepen.io/maoma87/pen/JaWQEq?editors=0010
Your links array contains only 1 element?
links: [{
"github": {
"link": "https://github.com/booleanaVillegas/juliana-villegas-taller-uno",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/github.svg?alt=media&token=83edf83c-cd80-43fa-bedd-a2348ff23b3e"
},
"web": {
"link": "https://enigmatic-shelf-33047.herokuapp.com/",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/web.svg?alt=media&token=b5e092a2-beb3-4c72-a329-8e402e82032f"
}
}]
If it's, you can loop like this:
<div class="links-container" v-for="(linkValue, key) in links[0]">
<a :href="linkValue.link" class="link-container"><img
:src='linkValue.logo' alt='key' class='link-img'></a>
</div>
Your v-for should once read array one element.
Links object a element like this
{
"github": {
"link": "https://github.com/booleanaVillegas/juliana-villegas-taller-uno",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/github.svg?alt=media&token=83edf83c-cd80-43fa-bedd-a2348ff23b3e"
},
"web": {
"link": "https://enigmatic-shelf-33047.herokuapp.com/",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/web.svg?alt=media&token=b5e092a2-beb3-4c72-a329-8e402e82032f"
}
}
So your v-for like this
<div class="links-container" v-for="link in links">
<a :href="link.github.link" class="link-container">
<img :src='link.github.logo' alt='link.key' class='link-img'>
</a>
<a :href="link.web.link" class="link-container">
<img :src='link.web.logo' alt='link.key' class='link-img'>
</a>
</div>

Q:How to if contidion from json on React in one component?

I want to make the type of product to add and hide things, can I use only one component because I do it right now with two. I have an if that renders ProductNew and ProductOld. Is it possible to make the differences in one compartment or not?
This is the json:
{
"products": {
"product": {
"type": "new",
"new": {
"text": "Some text..."
},
"attr": {
"price": "20"
}
},
"product2": {
"type": "old",
"attr": {
"price": "10"
}
}
}
}
It is possible, yes. Just pass the type as a property into your single component and then move the if statements into that.
So the calling code would look like
<YourComponent type="{this.props.type}" />
and the component would have, for example
<div>
{this.props.type == "New" ?
<span>New Stuff</span> :
<span>Old Stuff</span>
}
</div>
if you don't want anything in the old then just use
<div>
{this.props.type == "New" ?
<span>New Stuff</span> :
null
}
</div>

Polymer get property of object returned by filter

I have a javascript array with a lot of object, like so:
var myArray = [
{
"id": 1,
"name": "Name 1",
"active": false
},{
"id": 2,
"name": "Name 2",
"active": true
},{
"id": 3,
"name": "Name 3",
"active": false
}
]
I use the id parameter of these objects to compare them and store values. To get the object that belongs to that id, I have written a filter:
getTest: function(id){
var result = this.tests.filter(function(o){return o.id == id;} );
return result ? result[0] : null;
}
So I can easily use this filter inline. Now I'd like to get properties of the filtered result inline as well, for example:
<template if="{{ { id | getTest }.active">
You are active!
</template>
However doing this leads to an invalid expression. I've read through the docs multiple times, but don't quite see if this is even possivle.
How can I do this?
You can make a custom filter with an id parameter. That filter will take the item, verify if it has the good id, and the verify if it's active or not.
My original example was in this Plunker http://plnkr.co/edit/FSwzndyjRxJIymehsZIg?p=preview
Hope it helps! If it isn't exactly what you wanted to do, please ask, I'll try to answer further :)
[EDIT]
OK, after reading your comments, how about this:
<template is="auto-binding">
<h1>Hi !</h1>
<template repeat="{{item in myArray}}">
<template if="{{ item.active }}">
<p>
Item id:{{item.id}} is active! <br>
Amount of steps in this test: {{ item.steps }} <br>
Test description: {{ item.description }}
</p>
</template>
</template>
</template>
<script>
var template = document.querySelector('template[is="auto-binding"]');
template.count=0;
template.myArray = [
{
"id": 1,
"name": "Name 1",
"active": false,
"steps": 3,
"description": "Lorem"
},{
"id": 2,
"name": "Name 2",
"active": true,
"steps": 4,
"description": "Ipsum"
},{
"id": 3,
"name": "Name 3",
"active": true,
"steps": 5,
"description": "Lorem Ipsum"
}
];
</script>
Then you get the output you want:
Item id:2 is active!
Amount of steps in this test: 4
Test description: Ipsum
Item id:3 is active!
Amount of steps in this test: 5
Test description: Lorem Ipsum
The Plunker is http://plnkr.co/edit/nBYeeZ2Uw0EFihAhNYpl?p

Categories

Resources