iteration a json object on Ngfor in angular 2 - json

I'm having trouble iteration a json object in the Ngfor, there is my template :
template:
<h1>Hey</h1>
<div>{{ people| json}}</div>
<h1>***************************</h1>
<ul>
<li *ngFor="#person of people">
{{
person.label
}}
</li>
</ul>
people is the json object that I'm trying to iterate, I'm having rhe result of (people | json) and not getting the list, here is a screenshot:
and to finish, here is a part of json file :
{
"actionList": {
"count": 35,
"list": [
{
"Action": {
"label": "A1",
"HTTPMethod": "POST",
"actionType": "indexation",
"status": "active",
"description": "Ajout d'une transcription dans le lac de données",
"resourcePattern": "transcriptions/",
"parameters": [
{
"Parameter": {
"label": "",
"description": "Flux JSON à indexer",
"identifier": "2",
"parameterType": "body",
"dataType": "json",
"requestType": "Action",
"processParameter": {
"label": "",
"description": "Flux JSON à indexer",
"identifier": "4",
"parameterType": "body",
"dataType": "json",
"requestType": "Process"
}
}
},
please feel free to help me

Your people object isn't an array so you can iterate over it out of the box.
There is two options:
You want to iterate over a sub property. For example:
<ul>
<li *ngFor="#person of people?.actionList?.list">
{{
person.label
}}
</li>
</ul>
You want to iterate over the keys of your object. In this case, you need to implement a custom pipe:
#Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
if (!value) {
return value;
}
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]});
}
return keys;
}
}
and use it this way:
<ul>
<li *ngFor="#person of people | keys">
{{
person.value.xx
}}
</li>
</ul>
See this answer for more details:
How to display json object using *ngFor

Related

Can't read object of object Json file | angular | typescript | ngfor

Helloo !
i would use a json files in my angular-app.
I have a local json file 'client.json'
{
"T001": {
"name": "admin",
"type": "adm",
"id": "1",
"class": "viewer",
},
"T002": {
"name": "Customer",
"type": "usr",
"id": "2",
"class": "viewer",
},
"T003": {
"name": "DB450",
"type": "air",
"id": "3",
"class": "gateway",
},
"T004": {
"name": "DB620",
"type": "air",
"id": "4",
"class": "gateway",
}
}
Actually, i could read this file and i got access to the name of object (object of object) -- T003.name for example and using console.log to display the result but this is not what i'm looking for because i can't use this variable into html template.
import { Component, OnInit } from '#angular/core';
import * as tunnelsData from '../data/client.json'
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
objects: any;
ngOnInit(): void {
this.objects = (tunnelsData as any).default;
console.log(this.object);
}
}
I'm looking for loads this file into a variable, then using this variable on a html template with ngfor like this :
<my-app *ngFor="let T of objects"
[tunnel]="T"
[name]="T.name"><my-app>
tunnel and name are two variables of my second component
To display at the end an example like this :
Tunnel : T001 (which the first object of my file)
Name : admin (which an object of the first object)
.
.
.
I hope it's clear for you.
any idea please ?
Thank you.
The only problem is that you don't have an array in your json data. you have this data as an object
{
"T001": {
"name": "admin",
"type": "adm",
"id": "1",
"class": "viewer",
},
"T002": {
"name": "Customer",
"type": "usr",
"id": "2",
"class": "viewer",
},
"T003": {
"name": "DB450",
"type": "air",
"id": "3",
"class": "gateway",
},
"T004": {
"name": "DB620",
"type": "air",
"id": "4",
"class": "gateway",
}
}
And in your html you are trying to loop through your elements with ngFor. So ngFor directive always expects an array to loop in html.
So the simple solution you can have is that in your component you can do like this
app.component.ts
this.objects = (tunnelsData as any).default;
this.objectKeys = Object.keys(his.objects); // ['T001', 'T002', 'T003', 'T004']
And inside of your html you can do like this
<my-app *ngFor="let keyName of objectKeys" [tunnel]="objects[keyName]" [name]="objects[keyName]?.name"><my-app>
What i am doing here is that first i am getting all of the keys of your object as an array and then i am iterating over the array of keys. And in html i am accessing the individual object by it's key name which is coming from ngFor loop.
Generaly, angular does not support iterating over objects in ngFor.
Check your browser's dev tools console. There should be an error.
You can use pipe in ngFor to make it work KeyValuePipe.
For more details check this thread.
And to display the key (eg."T001"), you would need to pass it too.
*ngFor="let item of objects | keyvalue"
[tunnel]="item.value"
[name]="item.value.name"
[key]="item.key"

V-If inside V-for, inside V-for

I am a newbie with Vue and I am trying to run an IF statement inside two v-fors.
Basically I am trying to compare a value from one array of objects to a value of another array of objects and if true, render value from array of objects No 2.
Here is the code.
<div v-bind:class="[isActive ? 'projectsWorkingOnActive' : 'projectsWorkingOnInactive']" v-for="rec in listOfEmployees" v-bind:key="rec.id" >
<div v-for="proj in dummyProjectsData" v-bind:key="proj.id">
<div v-if="rec.name.display_value == proj.task_owner">
<h3>Projects Working On</h3>
<ul>
<li>{{proj.projects_working_on.project_name}}</li>
<li><submitbutton button_label="Hide Projects" #click="toggleClass()"></submitbutton></li>
</ul>
</div>
</div>
</div>
And here are my 2 arrays of objects.
const dummyProjectsData = [
{
ID: "44000005501077",
task_owner: "Denis Denchev",
projects_working_on: [
{
"project_name": "Project-1",
"project_id": "195000002362044"
},
{
"project_name": "Project-2",
"project_id": "195000002362045"
},
{
"project_name": "Project-3",
"project_id": "195000002362046"
},
]
},
{
ID: "44000005501078",
task_owner: "Jake Jones",
projects_working_on: [
{
"project_name": "Project-2",
"project_id": "195000002362044"
},
{
"project_name": "Project-5",
"project_id": "195000002362045"
},
{
"project_name": "Project-3",
"project_id": "195000002362046"
},
]
},
]
And the second array...
const listOfEmployees = [
{
"ID": "44000005527013",
"name": {
"display_value": "Denis Denchev",
"first_name": "Denis",
"last_name": "Denchev",
"prefix": "",
"suffix": "",
}
}
]
What am I doing wrong? It must be something silly that I am missing? Or can I not do if statement taking value from two v-for's ?
The problem is that proj.projects_working_on is an array of multiple projects, but you are trying to access a property on it like an object. Change to something like:
<div v-bind:class="[isActive ? 'projectsWorkingOnActive' : 'projectsWorkingOnInactive']" v-for="rec in listOfEmployees" v-bind:key="rec.id" >
<div v-for="proj in dummyProjectsData" v-bind:key="proj.id">
<div v-if="rec.name.display_value == proj.task_owner">
<h3>Projects Working On</h3>
<ul>
<li v-for="p in proj.projects_working_on" v-bind:key="p.project_id">
{{ p.project_name }}
</li>
<li><submitbutton button_label="Hide Projects" #click="toggleClass()"></submitbutton></li>
</ul>
</div>
</div>
</div>

Vue.js Filtered list Method

I am still learning Vue.js. At the moment I am trying to make a simple filtered list method that pulls the data from a json file in Vue. I think that I am having trouble figuring out the correct syntax.
I just cant seem to get it right. Any help is more than welcome :)
This is Vue file:
<template>
<section>
<ul>
<li v-for="product in rings" :key="product">
{{product.title}}
</li>
</ul>
</section>
</template>
<script>
import data from '#/assets/data.json';
export default {
data() {
return {
products: []
}
},
methods: {
computed: {
rings(){
return this.products.filter(product => product.type == 'Ring')
}
}
}
}
</script>
And this is the Json file:
{ "products": [
{
"title": "Ring 1",
"description": "something",
"type": "Ring",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Halskæde 1",
"description": "something",
"type": "Halskæde",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Armbånd 1",
"description": "something",
"type": "Armbånd",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Ørering 1",
"description": "something",
"type": "Ørering",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
}
]
}
You imported the data but never used anywhere inside the component:
import data from '#/assets/data.json';
// notice the data here is just a variable and it has nothing to do with the
// component's data property
export default {
data () {
return {
products: data.products // init products with imported data
}
},
Or with the destructuring syntax:
import { products } from '#/assets/data.json';
export default {
data () {
return {
products // init products with imported data
}
},

key value in ng-repeat and large JSON

I have jsons like this one:
JSON "myWelcome"
[
{"BACKGROUND": {
"BACK": {
"NAME": "asd"},
"AGE": "13",
"YEAR": "2016"
}},
{"NAILS": {
"BACK": {
"NAME": "asd"},
"AGE": {
"AG": "14"},
"YEAR": "2014",
"CENT": "dsds"
}}
]
What i need to do is show everything from this json in <ul> or table, but not by name. My HTML:
<ul ng-repeat="(key, value) in myWelcome">
<ul ng-repeat="val in value">
<ul ng-repeat="(o, values) in val">
<li>{{o}}</li><li>{{values}}</li>
</ul>
</ul>
</ul>
It not quite work because "NAME" in "BACK" shows all.
Thanks for answers in advance.
You can use this code to make it work, but it will only work on this data sample or a similar one, any changes in the JSON might break it also.
<ul ng-repeat="(key, value) in myWelcome">
<ul ng-repeat="val in value">
<ul ng-repeat="(o, values) in val">
<li>{{o}}</li><li ng-if="key=='NAILS'&& o=='AGE'" >{{values.ag}}</li><li ng-if="!key=='NAILS'&& o=='AGE'">{{values}}</li>
</ul>
</ul>
</ul>
You can first remove all the properties having key as NAME recursively then iterate using ng-repeat.
DEMO
var jsonObj = [
{"BACKGROUND": {
"BACK": {
"NAME": "asd"},
"AGE": "13",
"YEAR": "2016"
}},
{"NAILS": {
"BACK": {
"NAME": "asd"},
"AGE": {
"AG": "14"},
"YEAR": "2014",
"CENT": "dsds"
}}
];
function removeMeta(obj) {
for(prop in obj) {
if (prop === 'NAME')
delete obj[prop];
else if (typeof obj[prop] === 'object')
removeMeta(obj[prop]);
}
};
removeMeta(jsonObj);
console.log(jsonObj);

AngularFire2 avoid null value after ObjectObservable remove

I have a HTML list build with ngFor from AngularFire2 ObjectObservable.
Once a object(not last) is deleted from the Database, null appears in his position(index) and the HTML list tries to update but an error is thrown from the ngFor loop.
JSON from AngularFire2 DB:
let tasksList = {
"name": "Task list",
"items": [
{
"name": "Task 1"
},
{
"name": "Test 2"
},
{
"name": "Test 3"
}
]
}
HTML:
<ul *ngFor="let theTask of tasksList.items">
<li>{{theTask.name}}</li>
</ul>
After task 1 has been removed, the JSON looks like this:
let tasksList = {
"name": "Task list",
"items": [
null,
{
"name": "Test 2"
},
{
"name": "Test 3"
}
]
}
I think that the simplest solution would be to stop the null value from replacing the deleted object.
But is that possible?
Thank you
You can use angular 2's pipe (angular 1's filter) in order to filter all empty items:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({name: 'removeNull', pure: false})
export class RemoveNullPipe implements PipeTransform {
transform(items: any[]): any {
return items.filter(item => item);
}
}
then use it in HTML:
<ul>
<li *ngFor="let theTask of tasksList.items | removeNull">{{ theTask.name }}</li>
</ul>
I moved *ngFor from <ul> to <li> element, it seems better to repeat <li>s within <ul> and not repeat uls
plunker: http://plnkr.co/edit/IQq45kaJqqWRZOqhZdoe?p=preview