How can i fetch all json file data - ionic angular - json

I have this code and I can fetch data from (number) and (name) only, how can I fetch data from elements
I tried many ways, but I couldn't find a solution
Please help me
JSON
[
{
"number": 1,
"name": "ahmed",
"elements": [
{
"id": 1,
"text": "text1"
},
{
"id": 2,
"text": "text2"
},
{
"id": 3,
"text": "text3"
}
]
}
]
TS File
data: any;
constructor() {}
ngOnInit() {
fetch('./assets/data/datajson.json').then(res => res.json())
.then(json => {
this.data = json;
});
}
HTML
<ion-card mode="ios" *ngFor="let item of data; index as i">
<ion-item>
<ion-label>{{ item.name }}</ion-label>
</ion-item>
</ion-card>

You should iterate over inner key. in this case elements
<ion-card mode="ios" *ngFor="let item of data; index as i">
<ion-item>
<ion-label>{{ item.name }}</ion-label>
</ion-item>
<ion-item *ngFor="let ele of item.elements">
<ion-label>{{ ele.id}}-{{ele.text}}</ion-label>
</ion-item>
</ion-card>

Related

Customize mat select dropdown to allow nested values in angular

I'm customizing angular material select/autocomplete to allow nested dropdowns.
Here, I wanted to have one parent dropdown with many childs. If I expand particular parent dropdown, only childs of that dropdown should expand or collapse. Similarly, checkbox event should be selected in the same scenario.
Here, I got [object object] when I select the dropdowns.
console log is provided to give the values selected/unselected.
Can someone help on this?
STACKBLITZ
<mat-form-field appearance="fill">
<mat-label>Toppings</mat-label>
<input type="text" matInput placeholder="Select Users" aria-label="Select Users" matInput [matAutocomplete]="auto" [formControl]="states">
<mat-autocomplete #auto="matAutocomplete">
<mat-select-trigger>
{{states.value ? states.value[0] : ''}}
<span *ngIf="states.value?.length > 1" class="example-additional-selection">
(+{{states.value.length - 1}} {{states.value?.length === 2 ? 'other' : 'others'}})
</span>
</mat-select-trigger>
<mat-optgroup *ngFor="let group of stateList">
<div>
<mat-checkbox [checked]="group.selected" (change)="toggleParent($event, group)" (click)="$event.stopPropagation()">
{{group.letter}}
</mat-checkbox>
<button mat-button (click)="expandDocumentTypes(group)">
<mat-icon>keyboard_arrow_down</mat-icon>
</button>
</div>
<mat-option *ngFor="let name of group.names" [value]="name" [ngClass]="isExpandCategory[group.letter] ? 'list-show' : 'list-hide'">
<mat-checkbox [checked]="group.checked" (change)="toggleSelection($event, name, group)" (click)="$event.stopPropagation()">
{{name}}
</mat-checkbox>
</mat-option>
</mat-optgroup>
</mat-autocomplete>
</mat-form-field>
export class SelectCustomTriggerExample {
constructor(private _formBuilder: FormBuilder) {}
// stateForm: FormGroup = this._formBuilder.group({
// stateGroup: '',
// });
// toppings = new FormControl();
isExpandCategory: boolean[] = [];
toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
stateRecord: any = [];
states = new FormControl();
expandDocumentTypes(group: any) {
console.log("expanding dropdown", group);
this.isExpandCategory[group.letter] = !this.isExpandCategory[group.letter];
// expand only selected parent dropdown category with that childs
}
toggleSelection(event: any, name: any, group: any) {
debugger;
console.log("toggleSelection", name, event.checked, group);
if (event.checked) {
console.log("stastateRecordtelist", this.stateRecord);
this.stateRecord.push(name);
this.states.setValue(this.stateRecord);
console.log("toggleselection ", this.states.value);
} else {
this.stateRecord = this.stateRecord.filter((x: any) => x !== name);
console.log("else toggleselection", name, group, this.states.value);
this.states.setValue(this.states.value.filter((x: any) => x !== name));
console.log("after filter ", this.states.value);
//this.states.setValue([]);
}
}
toggleParent(event: any, group: any) {
debugger;
group.checked = event.checked;
console.log("event", event.checked, "group", group, "states value", this.states.value);
let states = this.states.value;
states = states ? states : [];
if (event.checked) {
states.push(...group.names)
} else {
console.log("else", states);
group.names.forEach((x: string) => {
if (states.indexOf(x) > -1) {
states.splice(states.indexOf(x), 1)
}
});
}
this.states.setValue(states);
console.log("statesvalue", this.states.value);
if (!event.checked) {
this.states.setValue(this.states.value.filter((x: any) => !x.includes(group.names)))
//this.states.setValue([]);
}
console.log("final statesvalue", this.states.value);
}
stateList = [{
"letter": "A",
"checked": false,
"names": [{
"id": 1,
"type": "Alabama"
},
{
"id": 2,
"type": "Alaska"
},
{
"id": 3,
"type": "Arizona"
},
{
"id": 4,
"type": "Arkansas"
}
]
},
{
"letter": "C",
"checked": false,
"names": [{
"id": 8,
"type": "California"
},
{
"id": 9,
"type": "Colorado"
},
{
"id": 10,
"type": "Connecticut"
}
]
},
{
"letter": "D",
"checked": false,
"names": [{
"id": 18,
"type": "Delaware"
},
{
"id": 19,
"type": "Denwer"
}
]
}
];
}
Expected output should look like below
Replace your toggleParent function with below given. You can also find solution in the stackblitz: https://stackblitz.com/edit/angular-f5mizr-final-pxdgby
toggleParent(event: any, group: any) {
debugger;
group.checked = event.checked;
console.log("event", event.checked, "group", group, "states value", this.states.value);
let states = this.states.value;
states = states ? states : [];
if (event.checked) {
states.push(...group.names.filter((x: any) => !states.includes(x.type)).map((x: any) => x.type))
} else {
console.log("else", states);
group.names.forEach((x: any) => {
if (states.indexOf(x.type) > -1) {
states.splice(states.indexOf(x.type), 1)
}
});
}
this.states.setValue(states);
console.log("statesvalue", this.states.value);
if (!event.checked) {
this.states.setValue(this.states.value.filter((x: any) => !x.includes(group.names)))
//this.states.setValue([]);
}
console.log("final statesvalue", this.states.value);
this.stateRecord = this.states.value;
}

Iteration of json file in typescript in angular?

[
{
"title": "Marker 1",
"innercontent": "the Porcelain Factory"
},
{
"title": "Marker 2",
"innercontent": "The Taj Mahal "
},
{
"title": "Marker 3",
"innercontent": "Golconda Fort"
}
]
The above is my json file.
<div *ngFor="let marker of currentmrkr">
<div>
{{ marker.title }}
</div>
<div>
{{ marker.innercontent }}
</div>
</div>
The above is my html file.
import * as content from './content.json';
marker.addListener("click", () => {for(let item of content){
if(marker.getTitle() == item.title){
this.currentmrkr = item;
}
}
}
The above is in my typescript file.
This shows an error like -
core.js:6260 ERROR TypeError: _content_json__WEBPACK_IMPORTED_MODULE_1___namespace is not iterable
How can we iterate through the json object inside the typescript file in angular and how to import the file into typescript?
If you want to iterate JSON within Typescript logic for let's say pushing data to firebase, you can use library called Lodash
import * as _ from 'lodash';
myfunction(json) {
return new Promise((resolve) => {
_.map(json, (e, i) => {
_.keys(e).map(() => {
this.afs.collection('library').doc('doc ' + i).set(e);
})
})
resolve();
})
}
I have a full blog on this if you need more details. Else if you defined a simple json object in typescript and want to view particular value in HTML you can use the following approach:
import { Component } from "#angular/core";
#Component({
selector: "app-some-section",
templateUrl: "./some-section.component.html",
styleUrls: ["./some-section.component.scss"],
})
export class SomeSectionComponent {
users = [
{
name: "Jacob",
job: "Analyst",
city: "California",
},
{
name: "John",
job: "Founder",
city: "New York",
},
];
constructor() {}
}
and then in the HTML template:
<div class="card" *ngFor="let user of users">
<h3 class="job">{{ user.job }}</h3>
<h3 class="name">{{ user.name }}</h3>
<h3 class="city">{{ user.city }}</h3>
</div>

Angular4 group by filter not working with pipe: ngx-pipes

I really trying to filter data that I need, filter products by price and by gender.
I used ngx-pipe, build pipe for sort the data. HTML:
<select [(ngModel)]="ProductCategory" (change)="updateProductCategory($ProductCategory)" name=Gender>
<option *ngFor="let g of GenderFilter">{{g.DisplayText}}</option>
</select>
<select [(ngModel)]="ProductCategory" (change)="updateProductCategory($ProductCategory)" name=Price>
<option *ngFor= "let k of PriceFilter ">{{k.DisplayText | groupBy: 'Value'}}</option>
</select>
<ul>
<li *ngFor="let store of stores">
<ul>
<li *ngFor="let product of store.Products">
<img src={{product.ProductImage}}>
<p>store: {{ store.StoreName }}</p>
<p>Product Price: {{ product.Price | currency}}</p>
<p>Product Title: {{ product.ProductTitle }}</p>
</li>
</ul>
</li>
</ul>
ts:
ProductCategory;
updateProductCategory(stringCategory: any) {
this.ProductCategory = stringCategory;
}
//getting the data from JSON
ngOnInit() {
this._storeService.getProducts()
.subscribe(data =>{
this.products = data.Stores.Products;
this.filtered = data.PriceFilter.TagId;
this.stores=data.Stores;});
JSONs like:
"PriceFilter": [
{
"TagId": 20,
"Type": "Budget",
"Value": 5,
"Values": null,
"DisplayText": "$5",
"Order": null
}]
"GenderFilter": [
{
"TagId": 3,
"Type": "Gender",
"Value": 3,
"Values": null,
"DisplayText": "Boy",
"Order": 1
}
Products:
"Stores": [
{
"Products": [
{
"ProductId": 206419,
"Price": 39.99,
"PriceLabel": "$39.99",
"ProductTags": [1,2,...]
}
]}]
My purpose is After selecting one of the values here,to filter the list to include all products with the same tag id my target
how it looks now:
Failure
Really need help!
Thank you very much!
Edited:
Console.log(Pricefilter)PriceFilter
This should be your snippet
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
filterProduct: ['']
})
}
getValue(index) {
if(index === 0)
return {
lower: 0,
displayText: this.PriceFilter[index].DisplayText,
upper: this.PriceFilter[index].Value
};
else {
return {
lower: this.PriceFilter[index - 1].Value,
upper: this.PriceFilter[index].Value,
displayText: `${this.PriceFilter[index - 1].DisplayText} - ${this.PriceFilter[index].DisplayText}`
};
}
}
ngOnInit() {
this.filteredProducts = [...this.Stores[0].Products];
this.myForm.get('filterProduct').valueChanges.subscribe(
value => {
console.log(value);
this.filteredProducts = [...this.Stores[0].Products.filter(product => product.Price >= value.lower && product.Price <= value.upper )]
}
)
}
}
<form [formGroup]="myForm">
<select name="Price" formControlName="filterProduct">
<option *ngFor="let k of PriceFilter; let i = index;"
[ngValue]="getValue(i)">
{{ getValue(i).displayText }}
</option>
</select>
</form>
<div>
<ul>
<li *ngFor= "let product of filteredProducts">
{{ product | json }}
</li>
</ul>
</div>

Angular call on JSON arrays

I want to output the title of test1 from the first array and the title
of test2 from the second array, any help would be great. Thanks
{
"results": [
{
"id": 21,
"title": "test1",
"identifier": null,
"colour_bg": "#bd2c2c",
"colour_btn": "#a11212",
"colour_content_bg": "#ffffff",
"logo_dashboard": "collection/21/SVwnz6tjluX81dIRNXjZo7issYUWyOVyD3LJFykm.png",
"logo_page": "collection/21/txgkqlkPA45mHSYtqZ5rFa4wLfHNUfXESE0xyhwp.png"
}
],
"links": [
{
"id": 21,
"title": "test2",
"identifier": null,
"colour_bg": "#bd2c2c",
"colour_btn": "#a11212",
"colour_content_bg": "#ffffff",
"logo_dashboard": "collection/21/SVwnz6tjluX81dIRNXjZo7issYUWyOVyD3LJFykm.png",
"logo_page": "collection/21/txgkqlkPA45mHSYtqZ5rFa4wLfHNUfXESE0xyhwp.png"
}
]
}
My HTML below
<div *ngFor="let result of data">
<h1>{{result.title}}</h1>
</div>
try like this :
stackblitz demo
in ts file :
loadUser() {
this.http.get('assets/json/collection.json')
.map(res => res.json())
.subscribe(data => {
this.data = data;
console.log('this.data', this.data);
})
}
template
<div *ngFor="let result1 of data.results">
<div *ngFor="let result2 of data.links">
<h1>{{result1.title}}</h1>
<h1>{{result2.title}}</h1>
</div>
</div>
<div *ngFor="let result of data; let idx = index">
<h1>{{result.title}}</h1>
<h1>{{links[idx].title}}</h1>
</div>

Ionic 3 filter nested JSON with ionic searchbar

I have a question how to use ionic searchbar to filter items in a nested JSON object. As I've tried to filter the header item it worked perfectly fine but it does not work for the name wrap inside the brands.
{
"items": [{
"header": "A",
"brands": [{ "name": "Apple", "id": "1" }, { "name": "Adidas", "id": "2" }]
},
{
"header": "B",
"brands": [{ "name": "Bose", "id": "3" }, { "name": "Boss", "id": "4" }, { "name": "Birkenstock", "id": "5" }]
},
{
"header": "M",
"brands": [{ "name": "McDonalds", "id": "6" }]
}
]
}
My search.ts:
private result: any[];
private searchItems: any;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private http: Http
) {
let localData = this.http.get('assets/search-brand.json').map(res => res.json().items);
localData.subscribe(data => {
this.result = data;
});
this.initializeItems();
}
initializeItems() {
this.searchItems = this.result;
}
getItems(ev: any) {
// Reset items back to all of the items
this.initializeItems();
// set val to the value of the searchbar
let val = ev.target.value;
// if the value is an empty string don't filter the items
if (val && val.trim() != '') {
this.searchItems = this.searchItems.filter((item) => {
return (item.header.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
}
My code (search.html):
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
<p>{{test}}</p>
<ion-list *ngFor="let item of searchItems; let i = index">
<ion-list-header>
{{item.header}}
</ion-list-header>
<ion-item *ngFor="let brands of item.brands; let j = index" (click)="selectedBrand(brands.id)">{{brands.name}}</ion-item>
</ion-list>
This one is working for filtering the brands.name it said .toLowerCase() is not a function.
Your JSON data maybe have some element with header == null or does not have brands propertive. So to ensure the search work properly, you should handle these case by if statement. You need to rewrite filter function to get expected output.
Try this:
this.searchItems = this.searchItems.map((item)=>{
if(item && item.brands && item.brands.length > 0){
item.brands = item.brands.filter(brand=>{
if(!brand.name) return false;
return brand.name.toLowerCase().indexOf(val.toLowerCase()) > -1;
});
}
retrun item;
})