How to iterate json object using ngFor in Angular 4 - arrays

Problem:
I have below code:
<div>
{{ data | json }}
</div>
which produces results in following json format
[
{
"display_title":"Megan Leavey",
"mpaa_rating":"PG-13",
"critics_pick":1,
"byline":"NEIL GENZLINGER",
"headline":"Review: In ‘Megan Leavey,’ a Marine, Her Dog and a Bond Forged in War",
"summary_short":"Based on a true story, this film, starring Kate Mara, is both harrowing and heartstring-tugging.",
"publication_date":"2017-06-08",
"opening_date":"2017-06-09",
"date_updated":"2017-06-09 02:44:28",
"link":{
"type":"article",
"url":"http://www.nytimes.com/2017/06/08/movies/megan-leavey-review-kate-mara.html",
"suggested_link_text":"Read the New York Times Review of Megan Leavey"
},
"multimedia":{
"type":"mediumThreeByTwo210",
"src":"https://static01.nyt.com/images/2017/06/09/arts/09MEGAN/09MEGAN-mediumThreeByTwo210.jpg",
"width":210,
"height":140
}
},
{
"display_title":"The Hero",
"mpaa_rating":"R",
"critics_pick":1,
"byline":"JEANNETTE CATSOULIS",
"headline":"Review: For an Aging Actor, Another Chance to Be ‘The Hero’",
"summary_short":"Brett Haley’s low-key feature, about an older actor seeking redemption after being reduced to a cliché, belongs to its star, Sam Elliott.",
"publication_date":"2017-06-08",
"opening_date":"2017-06-09",
"date_updated":"2017-06-09 02:44:28",
"link":{
"type":"article",
"url":"http://www.nytimes.com/2017/06/08/movies/the-hero-review-sam-elliott.html",
"suggested_link_text":"Read the New York Times Review of The Hero"
},
"multimedia":{
"type":"mediumThreeByTwo210",
"src":"https://static01.nyt.com/images/2017/06/09/arts/09HERO/09HERO-mediumThreeByTwo210.jpg",
"width":210,
"height":140
}
}
]
and my pipe codes
import { Pipe, PipeTransform} from '#angular/core';
#Pipe({name: 'keys'})
export class CustomPipe 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;
}
}
Using suggestion from iteration a json object on Ngfor in angular 2 ,
I am trying to achieve movie title like this:
<ul class="suggestions" >
<li class="suggestion1" *ngFor="#movie of data | keys">
{{ movie.display_title }}
</li>
</ul>
but it throws error like
zone.js:642 Unhandled Promise rejection: Template parse errors:
Parser Error: Unexpected token # at column 1 in [#movie of data | keys] in ng:///AppModule/RoughWorkComponent.html
I am using Angular 4.1.3

*ngFor="#movie of data | keys">
needs to be
*ngFor="let movie of data | keys">
you are using the old syntax
Edit: As #AJT_82 stated the object is an array not a JSON, so there's no need for the pipe:
*ngFor="let movie of data" is enough

Related

Filtering an array of JSON

Hey I am following another guide and really struggling to get it working for me. Somewhat new to Angular so I am sure this is a simple issue. Can anyone help me?
The front end shows all the JSON objects at the page load but when I type anything they all disappear.
_ninjaFilter:string
get ninjaFilter():string{
return this._ninjaFilter;
}
set ninjaFilter(value:string){
this._ninjaFilter = value
console.log(this.filteredNinjas, this.ninjaFilter)
this.filteredNinjas = this.ninjaFilter ? this.performFilter(this.ninjaFilter) : this.ninjas
}
performFilter(filterBy: string): any{
filterBy = filterBy.toLocaleLowerCase();
console.log(filterBy)
return this.ninjas.filter(ninja=>{
ninja.name.toLocaleLowerCase().includes(filterBy)
//tried a if statement here to console log match and it does log out match
//also have tried .indexOf(filterby) !== -1
})
}
filteredNinjas: any
ninjas=[{
'name':'yoshi',
'belt':'red'
},
{
'name':'luigi',
'belt':'black'
},
{
'name':'Ryu',
'belt':'green'
}]
constructor(private route: ActivatedRoute) {
this.filteredNinjas = this.ninjas //create new array to filter on
this.ninjaFilter='' //set initial filter string to null
}
and the view:
<h2>Ninja Listing</h2>
<input type='text' id="filter"
[(ngModel)]='ninjaFilter' />
<ul id="ninja-listing">
<li *ngFor="let ninja of filteredNinjas">
<div class='single-ninja'>
<span [ngStyle]="{background: ninja.belt}">{{ninja.belt}} belt</span>
<h3>{{ninja.name}}</h3>
</div>
</li>
</ul>
Here is console log (first page load and then me typing)
(3) [{…}, {…}, {…}] "r"
directory.component.ts:23 r
directory.component.ts:17 [] "ry"
directory.component.ts:23 ry
directory.component.ts:17 [] "ryu"
directory.component.ts:23 ryu
You don't return anything inside your filter function. You should return a condition there:
return this.ninjas.filter(ninja => {
return ninja.name.toLocaleLowerCase().includes(filterBy);
});

How to read attribute "name" of my json array in Ionic

json array localstorage format
Hello, I'm developing an ionic app. I'm new in Ionic and Typescript.
As you can see in the image below I'm parsing from an API my data in a json array.
On ts file I'm writing this code
`
public categoryDetails:any;
const datacat = JSON.parse(localStorage.getItem('categoryData'));
this.categoryDetails = datacat.categoryData;`
And in my html file when I write this
<h1 class="business-top">Business of the category {{categoryDetails.name}}</h1>
I get the error message "TypeError: Cannot read property 'name' of undefined"
I know that I don't read the attribute "name" correctly. How can I do this one?
Moreover, how can I display Businesses which associate with the spesific term_id of the category?
In this example you need to do that
<h1 class="business-top">Business of the category {{categoryDetails?.name}}</h1>
public categoryDetails: any;
this.categoryDetails = localStorage.getItem('categoryData');
or you can use ionic storage. it is better if you are using ionic.
https://ionicframework.com/docs/storage/
import { Storage } from '#ionic/storage';
export class MyApp {
public categoryDetails: any;
constructor(private storage: Storage) { }
...
// set a key/value
storage.set('categoryData', 'Max');
// Or to get a key/value pair
storage.get('categoryData').then((val) => {
this.categoryDetails = val;
});
}
I finally fingured it out.
#Kilomat thanks for your help and your advice about using ionic storage. That saved me from futured problems.
About my json file that's what I did.
In my HTML code
<ion-grid no-margin>
<h1 class="business-top">Επιχειρήσεις της κατηγορίας {{businessData.name}} {{businessData.term_id}}</h1>
<ion-list>
<ion-item class="col col-50" *ngFor="let c of BusinessCategoryDetails" text-wrap (click)="product(c)">
<div *ngIf="c.term_id == businessData.term_id">
<h2>{{c.post_title}} {{c.term_id}}</h2> <img width="80" height="80" src="{{c.guid}}">
</div>
</ion-item>
</ion-list>
</ion-grid>
And in my TS code
`var businessCategory: categories = navParams.get("businessCategory");
console.log(businessCategory); /exports the Selected category/
var newData = JSON.stringify(businessCategory);
this.businessData = JSON.parse(newData);`
Which takes properties and values from my previous category page. TS code
`categories: [categoryDetails] = null;
gotobusiness(category: categories){
this.navCtrl.push(BusinessPage, { businessCategory: category});
}`

Browse an array of months with 'ngFor' directive

My lack of knowledge in Angular 2 and typescript led me to this issue :
I want a datatable (already imported well) with all the months of the year on abscissa, and some DB objects on the ordinate (this is OK).
I don't know how and where to declare my list of months and how to browse it in my html.
A this moment, I have this :
Component.ts :
public months= {
1:'Janvier',
2:'Février',
3:'Avril',
etc...
12:'Decembre'
};
Component.html
<td *ngFor="let month of months">{{month}}</td>
Could you help me making it work (displaying at least a raw of months) and as clean as possible ? I'm pretty sure declaring a list of months directly in the class is not a good thing...
Thank you for reading
You have to make an array of months. Currently you have an object.
public months = ["Janvier", "Février", "Avril"...];
Or if you really want to have an object, you can implement custom pipe:
import { Injectable, Pipe } from '#angular/core';
#Pipe({
name: 'keyObject'
})
#Injectable()
export class KeyObjectPipe {
transform(value, args:string[]):any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]});
}
return keys;
}
}
And then you can use it as:
<td *ngFor="let month of months | keyObject">{{month.value}}</td>
Alternatively, you can use this way
months= [
{ 'id' :1 , 'name':'Janvier'},
{ 'id' :2 , 'name':'Février'},
{ 'id' :3 , 'name':'Avril'}
];
Accessing it in the ngFor as below
<div *ngFor="let month in months">
{{month.name}}</div>
</div>
Why not just use indexing in your view?
In your TS:
months = ["Janvier", "Février", "Avril"...];
In your HTML:
<div *ngFor="let month of months; let i = index">
<p>Month(string): {{month}}</p>
<p>Month(number): {{i+1}}</p>
</div>

How to do a filter for ngFor in angular2 that passes 5 values into it?

How to do a filter for ngFor in angular2 that passes 4 values into it?
This is where I current am with the filter code:
import { Pipe } from "#angular/core";
#Pipe({
name: 'mapFilter',
pure: true
})
export class MapFilter {
transform(items, [searchTerms]) {
return items;
}
}
This is my html
<tr *ngFor="let item of jobs | mapFilter: [searchTerm, county, region, type, markers]" class="animated fadeIn" (click)="viewJob(item)">
As you can see I'm trying to pass 5 values into the filter called: searchTerm, county, region, type, marker.
So I can then filter the result.
I'm not sure how to pass those into the filter. So mainly stuck on the mapFilter pipe code bit.
You could try the following:
<tr *ngFor="let item of jobs | mapFilter:searchTerm:county:region:type: markers"
class="animated fadeIn" (click)="viewJob(item)">
And get them in the pipe class this way:
#Pipe({
name: 'mapFilter'
})
export class MapFilter {
transform(items, searchTerms) {
let searchTerm = searchTerms[0];
let county = searchTerms[1];
(...)
return items;
}
}
I managed to get it working. Looks like they've changed the pipe. it now needs to look like this transform(items, searchTerm1, searchTerm2, SearchTerm3) {

Deep nested json to array in array / json rendering of Angular 2 *ngFor [duplicate]

This question already has answers here:
How to display json object using *ngFor
(4 answers)
Closed 6 years ago.
I want to list states and types of the following json with angular 2 *ngFor. The parental properties also should be rendered.
var test= {
'192-168-0-16':{
'ac395516-96d0-4533-8e0e-efbc68190e':{
'state': "none",
'typ': "test"
},
'ac395516-96d0-4533-8e0e-efbc68190e':{
'state': "none",
'typ': "dummy"
}
},
'222-21-12-12': {
'ac395516-96d0-4533-8e0e-efbc68190e': {
'state': "none",
'typ': "none"
}
}
Angular 2:
<div *ngFor='#s of test'> <!-- also other properties should be visible -->
<div *ngFor='#t of s'>
{{t.state}} {{t.typ}}
</div>
</div>
Of course this does not work. Is it possible without many data transforms? I am not sure how to get arrays of arrays of my json.
You need to use array with ngFor. If you want to use objects at this level, you should consider to use a custom pipe.
See this answer for more details:
How to display json object using *ngFor
Based on this, I would refactor your code this way:
<div *ngFor='#s of (test | keyValues)'>
<div *ngFor='#t of (s.value | keyValues)'>
{{t.value.state}} {{t.value.typ}}
</div>
</div>
with the following pipe:
#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;
}
}

Resources