Angular2 access nested JSON - angularjs

i´m new to Angular 2 in Typescript.I want to access D and G of my JSON with NgFor. Is there a way to access the elements?
[
{
"A":"B",
"C":{
"D": ["E","F"],
"G": ["H"]
}
}
]
I also createt a Plunker: Plunker

ngFor can't iterate over an object's keys out of the box. You must handle that yourself.
Pipes work well. Example: Updated Plunkr
#Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value: any, args?: any[]): any[] {
let keys = Object.keys(value),
data = [];
keys.forEach(key => {
data.push(value[key]);
});
return data;
}
}

Related

How to handle returning array with forkJoin() in Angular?

I'm using forkJoin() to handle multiple observables with this code:
forkJoin([
this.userRoleService.getAll(), // result is an array of UserRole models
this.userService.getOne(id), // result is a single User model
this.countyService.all(), // result is an array of County models
]).subscribe(([userRoles, userModel, counties]) => {
console.log(userRoles, userModel, counties);
// handle the result
});
As you see in results I need to get two arrays and a single object. But in this scenario I get this in the console:
(2) [UserRole, UserRole]
UserModel {api_endpoint: "user/", role: UserRole, id: 1, name: "admin", email: "admin#admin.test", …}
CountyModel {id: 20, name: "Hazard"}
Here I got one array with two of UserRole instances, one UserModel instance and one CountyModel instance.
Here is the county.service.ts:
import { Injectable } from '#angular/core';
import { CountyModel } from 'src/app/models/County.model';
#Injectable({
providedIn: 'root'
})
export class CountyService {
db: CountyModel[] = [];
constructor() {
const items = JSON.parse( localStorage.getItem('counties'));
items.forEach( (item: any) => {
this.db.push(new CountyModel().init(item));
});
}
all(): CountyModel[] {
return this.db ? this.db : [];
}
}
So the service's all() method return with an array in every case. But why I get only the last element of this array as result in the forkJoin and how can I catch all of the array elements?
You are not returning observable of array in countyService, try wrap it with of()
forkJoin([
this.userRoleService.getAll(), // result is an array of UserRole models
this.userService.getOne(id), // result is a single User model
of(this.countyService.all()), // result is an array of County models
])

How to loop through an array of objects, loop through each object and push each object into separate arrays for ngFor looping in angular

I am working on an Angular 7 project and I am dealing with an api that returns an array of (recipes)objects on search and I want to get the all ingredients from each object so I can loop through them, get only what I want because each (recipe)object varys from the other
I have tried looping through the initial array of objects and then looped through each individual object and getting only the available ingredients per (recipe)object but I do not know how to push them into separate arrays. Whenever I push, all ingredients from all the objects gets pushed into a single array.
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { RecipesService } from 'src/app/services/recipes.service';
#Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
s: string;
ingArray: any[] = []
measurementsArr = []
nothingFound = false;
itemsFound = false;
searchedData: any[] = [];
searchresults: number;
constructor(private route: ActivatedRoute, private service:RecipesService) { }
ngOnInit() {
this.route.queryParams.subscribe(params=>{
this.s = params.s;
console.log(this.s)
})
this.searchDB()
}
searchDB(){
this.service.searchRecipeDB(this.s).subscribe((res:any)=>{
if(res.meals === null){
this.nothingFound = true;
}else{
this.searchedData = res.meals
console.log(this.searchedData)
this.itemsFound = true;
this.searchresults=this.searchedData.length;
let resultsarray = this.searchedData
for(let y of resultsarray){
for(let obj in y){
if(obj.includes('strIngredient')){
if(y[obj]!=null){
if(y[obj].length > 0){
this.ingArray.push(y[obj])
console.log(this.ingArray)
}
}
}
}
}
}
})
}
}
I have been able to loop through and get each ingredients from each (recipe)object but have been unable to push them into separate arrays without having to define multiple arrays. Is there a way I can push all ingredients from a (recipe)object into a separate array without having other ingredients from other (recipes)object added? I do not want to define several arrays because I am working with an api and I do not know the expected search results all the time search results showing an array of objects
for(let y of resultsarray){
ingrSub: Array<any> = new Array();
for(let obj in y){
if(obj.includes('strIngredient')){
if(y[obj]!=null){
if(y[obj].length > 0){
ingrSub.push(y[obj])
console.log(this.ingArray)
}
}
}
}
if(ingrSub.length > 0)
this.ingArray.push(ingrSub)
else
ingrSub = null;//just to be sure that we do not leak the memory if engine thinks the oposite in some case
}
Just push obj, not y[obj]. Probably, I do not understand the task. And use of instead of in. Or do you wanna get some ingredient substrings from object?
this.array_a = [] <- this add your array
this.array_b.forEach(array_b_item => {
array_b_item.new_variable = JSON.parse(
JSON.stringify(this.array_a)
);
});
you can add values indivualy to array_b

Reading JSON into arrays in Angular (HttpClient)

i am trying to read JSON into different arrays using HttpClient for the use in Echarts, but since i am a newbie i couldn't find how to fill JSON into the different arrays.
the part code i used so far was:
....
label: Array<any>;
data: Array<any>;
tooltip: Array<any>;
constructor(private http: HttpClient) {
this.getJSON().subscribe(data => {
this.data=data.data;
this.label=data.label;
this.tooltip=data.tooltip;
console.log(data)
});
}
public getJSON(): Observable<any> {
return this.http.get("./assets/JSONData/TeamProgress.json")
}
the JSON file is formatted like this:
[{"label":"0","data":"0","tooltip":"0"},
{"label":"1","data":"-1","tooltip":" tooltip1"},
{"label":"2","data":"-1","tooltip":" tooltip2"},
...etc
i want to be able to get all labels of JSON in one array, and all data in another array, and all tooltips in a third array.
it would be great if you can help me.
thanks
First the result of that file should be a valid JSON structure aka (an object with key-values) you can group the array under a key called per example result
{
"result": [
{"label":"0","data":"0","tooltip":"0"},
{"label":"1","data":"-1","tooltip":" tooltip1"},
{"label":"2","data":"-1","tooltip":" tooltip2"},
//....Etc
]
}
Then you can access the data and filter it using map as below:
this.getJSON().subscribe((data:any) => {
this.label = data.result.map(element =>
// if you want to return an array of objects
{return {"label": element.label}}
// or if you want to return the raw values in an array, just do
element.label
});
this.data = data.result.map(element => {
return {"data": element.data}
});
this.tooltip = data.result.map(element => {
return {"tooltip": element.tooltip}
})
})

How to extract array from json on Angular

I'm working with angular2 ( version 5).
I make an http request an get back json.
I know how to access and use value but not the array.
and I don't find how to extract the two array inside element.
here my json:
{ "ImpiantiProva": [
{
"nomeImpianto":"MFL1",
"descrImpianto":"Multifilo 1",
"posizione":"Place1",
"dati_status": "true",
"unita_misura": "m/s",
"vel_attuale": 11.5,
"vel": [24.5,13.6,34.6,12.1],
"orario": ["17.05","17.06","17.07","17.08"]
},
{
"nomeImpianto":"MFL2",
"descrImpianto":"Multifilo 2",
"posizione":"Place2",
"dati_status": "true",
"unita_misura": "m/s",
"vel_attuale": 12.5,
"vel": [24.5,13.6,34.6,12.1],
"orario": ["17.05","17.06","17.07","17.08"]
}
]
}
In the data.service.ts I have the http request and it store values on :
stream$: Observable<ImpiantoModel[]>;
here my definition of the model:
#impianto.model
export class ImpiantoModel {
nomeImpianto: string;
descrImpianto: string;
posizione: string;
dati_status: string;
unita_misura: string;
vel_attuale: number;
vel: VelocitaModel[];
orario: OrariModel[];
}
#orari.model.ts
export class OrariModel {
orario: string;
}
#velocita.model.ts
export class VelocitaModel{
vel : number;
}
is it the right why to define my object?
How can I use the array "vel" and "orario"?
How can I print (access) the array "vel" of machine with "nomeImpianto" = "MFL1" ?
and how can I copy the array "vel" on new array?
thank you very much!
Here is what I understood of what you want to do : get the item in your json resp and put it in your object , so the best way is to create a static method directly when you get the json response, before returning the value create this adapter adaptImpiant(jsonObj) which will do something like :
adaptImpiant(jsonObj) {
let impiantTab = [];
jsonObj.ImpiantiProva.forEach((item) => {
let impiantoModel = {};
// impiantoModel = item if the model (below) match the item;
// if not manually set all your var like your velocita
let velocita = [] // is an array or an object with an array
// if class velocita = {}
velocita = item.vel.slice(0);
// if class velocita.valuesTab = item.vel.slice(0);
impiantoModel.velocita = velocita;
impiantTab.push(impiantoModel);
}
}
Your model seems wrong in this case, because you already use a ImpiantoModel array, so just create a class with whatever you want in :
#impianto.model
export class ImpiantoModel {
nomeImpianto: string;
descrImpianto: string;
posizione: string;
dati_status: string;
unita_misura: string;
vel_attuale: number;
vel: VelocitaModel // or simply [];
orario: OrariModel // or simply [];
}
I'm not sure I understand you, but I'll try.
is it the right why to define my object?
It should be:
export class ImpiantoModel {
nomeImpianto: string;
descrImpianto: string;
posizione: string;
dati_status: string;
unita_misura: string;
vel_attuale: number;
vel: Array<string>;
orario: Array<string>;
}
(But I have to confess, I don't know why model and not an interface)
How can I use the array "vel" and "orario"?
What do you mean?
How can I print (access) the array "vel" of machine with
"nomeImpianto" = "MFL1"
const thisContainsTheDataFromVel = whereYourDataIsStored['ImpiantiProva'].find((item) => { item['nomeImpianto'] === 'MFL1'})['vel'];
and how can I copy the array "vel" on new array?
UPDATE after reading your comment under this answer:
I took code from your example and added what you are missing. I made it so it can be more reusable (it can be enhanced even more, but I hope you understand the code and do what you need).
copyArray(data, targetValue) {
const mfl1Data = data.find((item) => item['nomeImpianto'] === targetValue);
if (mfl1Data) {
return mfl1Data.vel;
}
return [];
}
getdata2() {
this.http.get<ImpiantoModel[]>(this.myUrl)
.subscribe(
data => {
this.variableToStoreIn = this.copyArray(data, 'MFL1');
data.forEach(item => {
this.sub$.next(item);
});
});
return this.sub$;
}
CopyArray finds the data and returns it. If you don't want it like this, but just set a value of some property to the value of vel array then you can change it to:
copyArray(data) {
const mfl1Data = data.find((item) => item['nomeImpianto'] === targetValue);
if (mfl1Data) {
this.yourVariable = mfl1Data.vel;
}
}
If this answer is sufficient, please consider to mark it as the best answer, thank you.
According to your model classes, your JSON is wrong. You should have something like this:
{ "ImpiantiProva": [
{
"nomeImpianto":"MFL1",
"descrImpianto":"Multifilo 1",
"posizione":"Place1",
"dati_status": "true",
"unita_misura": "m/s",
"vel_attuale": 11.5,
"vel": [
{
"vel": 24.5
},
{
"vel": 13.6
}
...
],
"orario": [
{
"orario": "17.05"
},
{
"orario": "17.06"
}
...
]
}
]
}
Your model expects ImpiantoModel.vel and ImpiantoModel.orario to be arrays of objects. In your JSON response one is an array of numbers and the other of strings.
An if you want to use it in an HTML template, considering that you have a class attribute in your .ts file like this:
private impiantoModels: ImpiantoModel[];
You could do something like this inside your .html template:
<div *ngFor="let impModel of impiantoModels">
...
<div *ngFor="let v of impModel.vel">
<p>{{v.vel}}</p>
</div>
<div *ngFor="let o of impModel.orario">
<p>{{o.orario}}</p>
</div>
</div>

print attributes values from JSON array in Angular2

I'm using Angular2 and I have retrieved some data from Firebase in this way:
dataset: any;
onGetData() {
this._dataService.getAllData()
.subscribe(
data => this.dataset = JSON.stringify(data),
error => console.error(error)
);
if I print dataset I get this JSON:
{"-KE8XuCI7Vsm1jKDJIGK":{"content":"aaa","title":"bbb"},"-KE8XvM268lWhXWKg6Rx":{"content":"cccc","title":"dddd"}}
How can I print out a list made up of only the title values from this JSON array?
I'd like to have: bbb - dddd
You can only iterate over an array using ngFor. In your case you need to implement a custom pipe to iterate over keys of an object.
Something like that:
#Pipe({name: 'keyValues'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]);
}
return keys;
}
}
and use it like that:
<span *ngFor="#entry of dataset | keyValues">
Title: {{entry.value.title}}
</span>
See this question for more details:
How to display json object using *ngFor
In your view you need
<div *ngFor='#data of dataset'>
{{ data.title }} -
</div>

Resources