In the above screenshot console I have an object with 2 values users and tickers. Again each one is array of values.
Now how to display these values in angular5 html template as specified in above screenshot?
I am trying to use ngFor but it is showing errors.
Suppose this is your data:
public data = {
tickers:[
{id:"1",name:"Ticker Name 1", company:"Company 1"},
{id:"2",name:"Ticker Name 2", company:"comapny 2"}
],
users:[
{id:"1",first_name:"User1 ", last_name:"u1last", email:"user1#test.com"},
{id:"2",first_name:"User2", last_name:"u2last", email:"user2#test.com"},
{id:"3",first_name:"User3", last_name:"u3last", email:"user3#test.com"},
{id:"4",first_name:"User4", last_name:"u4last", email:"user4#test.com"}
]
};
public dataKeys; // This will hold the main Object Keys.
The constructor will look something like this:
constructor() {
this.dataKeys = Object.keys(this.data);
}
Here is the simple HTML that you need to write:
<div *ngFor="let key of dataKeys">
<h3>{{ key }}</h3>
<ul>
<li *ngFor="let d of data[key]">{{d.name || d.first_name}}</li>
</ul>
</div>
Here is the complete working plunker for your case:
Click here to view the Working Solution
you can use like that,
<ul>
<P>users</p>
<li *ngFor="let item of object.users; let i = index">
{{i}}. {{item.frist_name}}
</li>
<P>Tickets</p>
<li *ngFor="let item of object.tickers; let i = index">
{{i}}. {{item.name}}
</li>
</ul>
According to the documentation it should be this:
Users:
<ol>
<li *ngFor="let user of users">{{user.first_name}}</li>
</ol>
Tickets:
<ol>
<li *ngFor="let ticket of tickets">{{ticket.name}}</li>
</ol>
You can use json pipe for debug purpose like this:
{{object |json}}
If you want exactly as in picture, look at this solution. With this case, you don't need to manually write first level property names of object in template for using *ngFor
Related
Is there a way to include button in this code which will with click make the same change to an array the same way [ngStyle] does in the following part of the code?
app.component.html
<div class="styling">
<ul>
<li *ngFor = "let a of arr"
[ngStyle]="changeFont()">
{{a}}
</li>
</ul>
</div>
app.component.ts
arr=['car','house','beach','microphone'];
changeFont(){
return {'font-size.px':15}
}
In Angular you has variables in .ts, and use this variables in the .html.
An example
style:any=null //declare a variable
toogleStyle() //A function that change the variable
{
if (!this.style)
this.style={'font-size':'15px';color:'red'}
else
this.style=null
}
You can use
<div (click)="toogleStyle()" [ngStyle]="style">click me!</div>
And see how change the style
As you has "severals" <li> you need severals variables if you want severals<li> can be "selected" at time or an unique variable if only one <li> can be selected at time.
The "severals variables" are an Array, so to change one element of
the array you need pass the "index" of the array
styles:any[]=[]
toogleStyle(index:number) //A function that change the variable
{
if (!this.styles[index])
this.styles[index]={'font-size':'15px';color:'red'}
else
this.styles[index]=null
}
<ul>
<!--see using let i=index, i becomes value 0,1,2,3...->
<li *ngFor = "let a of arr;let i=index"
<!--see you pass the "index" to the function-->
[ngStyle]="styles[i]" (click)="toogleStyle(i)">
{{a}}
</li>
</ul>
The unique variable is a number that is the "index" selected. For no
selected index, the variable becomes -1 (Remember that 0 is the fisrt
element of the array)
selectedIndex:number=-1
toogleStyle(index:number) //A function that change the variable
{
if (this.selectedIndex==index) //if you click on selected <li>
this.selectedIndex=-1;
else
this.selectedIndex=index;
}
<ul>
<li *ngFor = "let a of arr;let i=index"
<!--you use the conditional operator (condition)?
value if condition is true:
value if condition is false
-->
[ngStyle]="i==selectedIndex?
{'font-size':'15px';color:'red'}:
null"
(click)="toogleStyle(i)">
{{a}}
</li>
</ul>
I am creating a tree menu, visually it looks like this:
The tree has been created based on an array of objects obtained from a service, extracted from a date property.
Now, I have to get the tree menu to allow displaying and collapsing the: years, months and complete dates, in the style of this component:
https://angular2-tree.readme.io/
Ideally, I'd do this with typescript, but if it's hard for me, I'd try using an external component.
This is the html code:
<ul>
<li *ngFor="let y of tree | keyvalue">{{y.key}}
<ul>
<li *ngFor="let m of tree[y.key] | keyvalue">{{m.key}}
<ul>
<li *ngFor="let d of tree[y.key][m.key] | keyvalue">{{d.key}}
<ul>
<li *ngFor="let h of tree[y.key][m.key][d.key]"><a [ngClass]="{'hourSelected': (idSchedule === h.id || lastId === h.id),'hourUnSelected': idSchedule !== h.id}" (click)="loadMacroProcesses(h.id)">{{h.hour}}</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This would be the solution, now I will refine it:
<ul>
<li id="year" *ngFor="let y of tree | keyvalue; let i=index" (click)="listClick($event, i)">{{y.key}}
<ul [hidden]="indexExpandedYear!=i?true:null">
<li id="month" *ngFor="let m of tree[y.key] | keyvalue; let j=index" (click)="listClick($event, j)">{{m.key}}
<ul [hidden]="indexExpandedMonth!=j?true:null">
<li id="day" *ngFor="let d of tree[y.key][m.key] | keyvalue; let k=index" (click)="listClick($event, k)">{{d.key}}
<ul [hidden]="indexExpandedDay!=k?true:null">
<li *ngFor="let h of tree[y.key][m.key][d.key]"><a [ngClass]="{'hourSelected': (idSchedule === h.id || lastId === h.id),'hourUnSelected': idSchedule !== h.id && lastId !== h.id}" (click)="loadMacroProcesses(h.id)">{{h.hour}}</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This is the typescript method:
listClick(event, i) {
switch (event.srcElement.id) {
case "year":
this.indexExpandedYear = this.indexExpandedYear==i?-1:i;
event.stopPropagation();
break;
case "month":
this.indexExpandedMonth = this.indexExpandedMonth==i?-1:i;
event.stopPropagation();
break;
case "day":
this.indexExpandedDay = this.indexExpandedDay==i?-1:i;
event.stopPropagation();
break;
default:
break;
}
}
Can you recommend me a good one external component? Thanks.
NOTE: I am working with version 11 of Angular
NOTE: If you deploy one year, the rest of the years should be collpased back.
NOTE: Angular material is not valid for me
You could add a parameter for visibility and click event to the parent ul. How it would work is that they would have a boolean value on them for visibility that would change when you click the top ul element. You would have a method that would just switch between true/false and display if true hidden if false. Click event should be on the top li element and visibility on its child.
You should checkout the tree component provided by primeng. It has its own data format and can do your own customisation on top it.
I have an array of items that need to be displayed based on roles. I need the first value which will fulfil the ngIf condition.
I am adding my code below:
My Array(kind of how it will originally look):
parentTabList = [
{
name: 'abc',
label: 'abc',
icon : 'question_answer',
role : ['vend_perm','vend_temp','vend_subs']
},
{
name: 'xyz',
label: 'xyz',
icon : 'question_answer',
role : ['vend_perm','vend_subs']
}
]
My Html: -
<ng-container *ngFor="let form of parentTabList let i = index">
<li *ngIf="form.role.includes(userRole)">
<a (click)="methodName(form)">
{{form.label}}
</a>
</li>
</ng-container>
UserRole is a string value that I get when a user logs-in.
I need to add a ngClass to the anchor tag if it is the first anchor to be displayed.
(I am a noob at StackOverflow, please let me know if any more explanation is required).
You can identify first element of the array with index.
But as per my understanding you need filter this array with roles and then apply ngClass to first element from filtered list.
So add method to return filtered array with respect to roles
In Template:
filterParentTabList(parentList: any) {
return parentList.filter(form => form.role.includes(this.userRole));
}
In View:
<ng-container *ngFor="let form of filterParentTabList(parentTabList); let i = index">
<li>
<a [ngClass]="{ 'addYourClaaName': i === 0 }" (click)="methodName(form)">
{{form.label}}
</a>
</li>
</ng-container>
Happy Coding.. :)
You can write like this. In this code, f represents the first position of your array.
<ng-container *ngFor="let form of parentTabList; let i = index; let f = first">
<li *ngIf="f">
<a (click)="methodName(f)">
`{{f.label}}`
</a>
</li>
</ng-container>
If you want other position of your array, you can write like you mentioned above.
You can define a getter that will get you the index. This can then be used in the html
get firstIndex() {
return this.parentTabList.indexOf(this.parentTabList.find(({role}) =>
role.includes(this.userRole)))
}
Now in your html
<ng-container *ngFor="let form of parentTabList let i = index">
<li *ngIf="form.role.includes(userRole)">
<a [ngClass]="{redText: firstIndex === i}" (click)="methodName(form)">
{{form.label}}
</a>
</li>
</ng-container>
See Stackblitz Demo Here
I have an array in angular as follows
$scope.arr={
"abc/xyz/../": [
"a1.txt",
"a2.txt",
"a3.txt"
],
"": [
"no-folder.txt"
],
"abc1/xyz/../": [
"a4.txt",
"a5.txt",
"a6.txt"
]
}
i want to iterate through this array and need to get the results as follows
"a1.txt",
"a2.txt",
"a3.txt"
and
"no-folder.txt"
and
"a4.txt",
"a5.txt",
"a6.txt"
i have tried as follows
<div ng-repeat="test in arr track by $index">
<h3 ng-repeat="(key, value) in test">
{{value}}
</h3>
</div>
but i am getting strange results as each character is coming as result .
can u pleas help.
update
please look to this fiddle
https://jsfiddle.net/771voyj6/8/
I don't know what you want to do but you can create your logic something like this it might work for you ,its some hardcoded work but change it accordingly
$scope.test = []
$scope.test.push(arr["abc1/xyz/../"]+arr[""]+arr["abc1/xyz/../"]);
Use test in ng-repeat .. :)
or you can do what i know with your code use ng-repeat like this for your code:
<div ng-repeat="test in arr">
<div ng-repeat="test2 in test">
{{test2}}
</div>
I don't know if Pankaj is right regarding the empty key value. But certainly your $scope.arr is not an array but an object.
As such your code should be:
<div ng-repeat="(key, value)in arr track by $index">
<h3 ng-repeat=" item in value">
{{item}}
</h3>
</div>
I suspect that the JSON you are getting is not valid JSON. In second second property of your object is ""(blank) which would be invalid JSON.
JSON
{
"abc/xyz/../": [
"a1.txt",
"a2.txt",
"a3.txt"
],
//in below line json has no key
"": [
"no-folder.txt"
],
"abc1/xyz/../": [
"a4.txt",
"a5.txt",
"a6.txt"
]
}
Update
Apology for having wrong conceptualization regarding JSON, above JSON is valid JSON (but technically JSON shouldn't have blank key). I tried the above code in Fiddle which is working fine.
Working Fiddle(Angular 1.4.8)
You need to replace your HTML code with the following:
<div ng-repeat="test in arr track by $index">
<div ng-repeat="item in test">
{{item}}
</div>
</div>
I am getting the result. Please check the following JSFiddle:
http://jsfiddle.net/akonchady/a25r1mm4/3/
If I have an object like the following:
languages = {
"ar":{
"name":"Arabic",
"nativeName":"العربية"
},
"bg":{
"name":"Bulgarian",
"nativeName":"български език"
},
"ca":{
"name":"Catalan; Valencian",
"nativeName":"Català"
}...
}
And I loop through it in a list like so:
<ul>
<li ng-repeat="lang in languages"><a ng-click="select(lang)">{{lang.nativeName}}</a></li>
</ul>
Is there a way to get the object key in the select function without also putting the key in the object itself?
i.e:
languages = {
"ar":{
"name":"Arabic",
"nativeName":"العربية",
"key":"ar"
},
Thanks.
You could do like below:
<ul>
<li ng-repeat="(key, lang) in languages"><a ng-click="select(key)">{{lang.nativeName}}</a></li>
</ul>