Display content of a list in Angular 2? - html

I am new in Angular. I am creating a component in which I am creating a list of int. An example of the content of the list is 13,14,15,22,23,24.
I want to display this content on screen in a specific way. I want the continiously integeres to be in one line and the others in the second line. For example I want this:
13:00, 14:00, 15:00 button
22:00, 23:00, 24:00 button
I am trying this but I don't want a continious list, I want two parts of the list.
<ul>
<li *ngFor="let int of listindexdisabled">{{int}}:00 </li>
</ul>
Can someone help?

Why don't we try to set up two loops with a SlicePipe to iterate on a portion ( 13 -> 15 and second loop 2 -> 24 )?
If you have non dynamic list and you list will always need to be cut at a certain index , this should help you
https://angular.io/api/common/SlicePipe
<ul>
<li *ngFor="let int of listindexdisabled | slice:0:3">
{{int}}:00
</li>
</ul>
<ul>
<li *ngFor="let int of listindexdisabled | slice:3:6">
{{int}}:00
</li>
</ul>
otherwise , i think that this should works
<ul>
<ng-container *ngFor="let int of listindexdisabled">
<li *ngIf="int < 22">
{{int}}:00
</li>
</ng-container>
</ul>
<ul>
<ng-container *ngFor="let int of listindexdisabled">
<li *ngIf="int > 21">
{{int}}:00
</li>
</ng-container>
</ul>

You can try this below code
<ul>
<li *ngFor="let int in listindexdisabled">{{int}} : 00</li>
</ul>

Here is a sample of what you could do: repro on Stackblitz
And in case stackblitz is not working, here is the code :
.html :
<ul *ngFor="let chunk of displayedValues">
<li>
<span *ngFor="let value of chunk">{{value}}:00 - </span>
</li>
</ul>
.ts :
import { Component, OnInit } from '#angular/core';
import { getAttrsForDirectiveMatching } from '#angular/compiler/src/render3/view/util';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
values = [13,14,15,18,19,22,23,24];
displayedValues = [];
ngOnInit(){
this.customChunk();
}
customChunk(){
let array = [];
this.values.forEach(val => {
if(array.length === 0
|| val === array[array.length-1] + 1){
array.push(val);
} else {
this.displayedValues.push(array);
array = [];
}
});
// add the last chunk
this.displayedValues.push(array);
}
}
The idea is to rework your array into an array of chunk made by numbers that follow themselves. Then you just have to do a loop inside a loop to display your values.

Related

How to manipulate json initialised with key into ngFor in angular 8

I have a json initialised with key(key can be change,its dynamic), I need to manupulate into ngFor as per the static html.I have already tried but not working so I commented.Value of 'mainitem' will come as a heading and key of 'Seconditem' will come inside li tag.Here is the code below and demo https://stackblitz.com/edit/angular-ufbwzw?file=src%2Fapp%2Fapp.component.ts
app.component.html
<p>
Start editing to see some magic happen :)
</p>
<!--<div>
<ul>
<ng-container *ngFor="let item of jsonarray">
<h5>{{item.mainitem}}</h5>
<li *ngFor="let subItem of item.Seconditem | keyvalue">
{{subItem.key}} - {{subItem.value}}
</li>
</ng-container>
</ul>
</div>
-->
<div>
<ul>
<h5>My item 1</h5>
<li>createddate</li>
<li>enddate</li>
<h5>My item 2</h5>
<li>origindate</li>
<li>startdate</li>
</ul>
</div>
app.component.ts
import { Component, OnInit } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
name = "Angular";
jsonarray = {
"575": [
{
mainitem: "My item 1",
Seconditem: {
createddate: "30-01-02",
enddate: "30-01-03"
}
},
{
mainitem: "My item 2",
Seconditem: {
origindate: "30-01-04",
startdate: "30-01-05"
}
}
]
};
ngOnInit() {}
}
<ul>
<ng-container *ngFor="let item of jsonarray | keyvalue">
<ng-container *ngFor="let value of item.value">
<h5>{{value.mainitem}}</h5>
<li *ngFor="let subItem of value.Seconditem | keyvalue">
{{subItem.key}} - {{subItem.value}}
</li>
</ng-container>
</ng-container>
</ul>
Working Stackblitz :- https://stackblitz.com/edit/angular-kfwv4m?file=src/app/app.component.html

Incrementing date in angular template

I have something like below and i need to display dates incrementally
<ul>
<li *ngFor="let item of items">
<h2>
{{item.name}}
</h2>
<p >
{{item.description}}
</p>
<time>{{date | date:'dd/MM/yyyy'}}</time>
</li>
</ul>
dates need to be shown as for first item it shows today's date and then tomorrow and so on.
If there is a way that it can be done only by using html template then its better. Or just help with the best way to do this.
I don't think there is a way to do this with only the date pipe, its primary use is morphing a current date into a different display. Not adding/removing. Something you could do is create your own date pipe that has an offset option
Solution 1
Creating a new pipe and using the moment library
import {Pipe, PipeTransform} from '#angular/core';
import * as moment from 'moment';
#Pipe({name: 'customDate'})
export class CustomDatePipe implements PipeTransform {
transform(date, format = 'dd/MM/yyyy', dayOffset = 0, monthOffset = 0, yearOffset = 0) {
return moment(new Date(date)).add(dayOffset, 'days')
.add(monthOffset, 'months')
.add(yearOffset, 'years')
.format(format);
}
}
and then reference it in html as this
<ul>
<li *ngFor="let item of items; let i = index">
<span>{{date | customDate: 'dd/MM/yyyy': i}}</span>
</li>
</ul>
Solution 2
Or you can use vanilla javascript Date along with a custom pipe
import {Pipe, PipeTransform} from '#angular/core';
#Pipe({name: 'customDate'})
export class CustomDatePipe implements PipeTransform {
transform(date, format = 'dd/MM/yyyy', dayOffset = 0) {
return new Date(date).addDays(dayOffset);
}
}
and reference it like this
<ul>
<li *ngFor="let item of items; let i = index">
<span>{{date | customDate: i | date: 'dd/MM/yyyy'}}</span>
</li>
</ul>

change background color based on response attributes Angular

I had request data from API, then I got response Object, so using *ngFor, I had managed to display some data that I want, problem is that are some css need to be implemented based on response attribute, for my data, I had list of bank and status. based on attribute status Offline
I need to change background color and need only show Offline status only.I had managed to change the background color, this is what I had tried:
html file
<ul class="ul1">
<li
[style.background]="getBackgroundColor(p.status)"
class="li1" *ngFor="let p of myData?.paymentChannels">
<span>{{p.name}}</span>
<br>
<span>{{p.status}}</span>
</li>
</ul>
ts file
getBackgroundColor(status) {
switch (status) {
case 'Offline':
return 'grey';
}
}
expected output:
also this is my stackblitz demo, I could use some suggestion to solve mine.
I would suggest something like this:
<ul class="ul1">
<li
[ngClass]="{offline: p.status == 'Offline'}"
class="li1" *ngFor="let p of myData?.paymentChannels">
<span>{{p.name}}</span>
<br>
<span> {{p.status == 'Offline' ? p.status : ' '}}</span>
</li>
</ul>
And add to css:
.offline {
background-color: gray;
}
your code is working but I think it's better without function like this:
<ul class="ul1">
<li [style.background]="'grey' : p.status == 'Offline'" class="li1"
*ngFor="let p of myData?.paymentChannels">
<span>{{p.name}}</span>
<br>
<span>{{p.status}}</span>
</li>
</ul>
Before
<span>{{p.status}}</span>
After
<span>{{p.status === 'Offline' ? 'Offline' : ' '}}</span>
It would be even better if you would extract the logic to a method withing the TS file.
The ' ' part is a placeholder (blank space) so the box do not collapse, but I would recommend adding the proper CSS styling, for instance, adding min-height: 36px; to the class .li1 would suffice.
StackBlitz
You can filter your data using structural directive *ngIf and then apply styling:
<ul
*ngIf="myData?.paymentChannels"
class="ul1">
<li
[style.background]="p?.status === 'Offline'? 'grey' : 'green'"
class="li1"
*ngFor="let p of myData?.paymentChannels">
<ng-container *ngIf="p?.status === 'Offline'">
<span>{{p.name}}</span>
<br>
<span>{{p.status}}</span>
</ng-container>
</li>
</ul>
If you want to filter and your array of data is small, then you can use *ngIf directive. However, it would be better to use filter pipe:
<li *ngFor="let item of myData?.paymentChannels | yourFilter:filterargs">
and your pipe:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'myfilter',
pure: false
})
export class YourFilterPipe implements PipeTransform {
transform(items: any[], filter: Object): any {
if (!items || !filter) {
return items;
}
// filter items array, items which match and return true will be
// kept, false will be filtered out
return items.filter(item => item.title.indexOf(filter.title) !== -1);
}
}
and you should include your pipe into app.module.ts:
import { YourFilterPipe } from './shared/pipes/your-filter.pipe';
#NgModule({
imports: [
..
],
declarations: [
YourFilterPipe,
],
providers: [
..
],
bootstrap: [AppComponent]
})
export class AppModule { }
Please, see the example at stackblitz.com
UPDATE:
If you do not want to filter data, but hide status offline you can use *ngIf structural directive:
<ul
*ngIf="myData?.paymentChannels"
class="ul1">
<li
[style.background]="p?.status === 'Offline'? 'grey' : 'green'"
class="li1"
*ngFor="let p of myData?.paymentChannels">
<span>{{p.name}}</span>
<br>
<span *ngIf="p?.status === 'Offline'; else empty">{{p.status}}</span>
<ng-template #empty>$nbsp;</ng-template>
</li>
</ul>

Using ng-repeat or ngFor to display each object in a JSON object as individual list items

I recieve an object that looks like this:
I'm trying to use ng-repeat to display the "Message", "Priority" and "DateTime" properties of each object as li items in a ul.
I've tried a couple of approaches including ng-repeat and ngFor, where all have been wrapped in divs like the first option:
This seems like the proper way to do it, but returns exactly nothing:
<div style="background: red;">
<ul>
<li ng-repeat="Notification in allNotifications">{{Notification}}</li>
</ul>
</div>
This option returns the specific object as expected:
<li style="border-radius: 3px"
[ngStyle]="{'color' : alertText}" >
Notification: {{ allNotifications.Notifications['0'].Message['0'] }}
</li>
Doesnt compile:
<li style="border-radius: 3px"
[ngStyle]="{'color' : alertText}"
[ngFor]="let subItem of allNotifications.Notifications['0'].Message['0']">
Notification: {{ subItem }}
</li>
My TS looks like this:
export class EventLogComponent implements OnInit {
constructor(private _dashdata: DashdataService) { }
NotificationName: string;
alertText: string;
allNotifications: JSON;
ngOnInit() {
this.NotificationName = 'NoNameAvailable';
this.alertText = 'Black'; //TODO: set color according to threatlevel
setInterval(() => {
this._dashdata.getAllNotifications()
.subscribe(res => {
this.allNotifications = res['notificationdata'];
console.log(this.allNotifications);
});
}, 5000); // Data Update interval in MS
}
}
ng-repeat is directive of framework AngularJS.
You are using Angular so in your case you should use ngFor:
<div style="background: red;"> <ul> <li *ngFor="let notification of allNotifications">{{notification}}</li> </ul> </div>
Using angular you should forget ng-repeat that is apart of AngularJS (version <= 1.6)
I think you have a double problem, the first one, as said, is ng-repeat, the second one is that you are not well targeting your data.
Try this
template
<div style="background: red;">
<ul>
<li *ngFor="let not of allNotifications.Notification">{{not}}</li>
</ul>
</div>

Nested JSON data loop for *ngFor in angular 5/4

I am new to angular,
I have created a service to loop the nested json data for my list.
export const CATEGORIES: Category[] = [
{
id: 1,
categoryName:'Accessories',
subcatName: [
{subcategory: 'belts',}
],
},
{
id: 2,
categoryName:'Clothing',
subcatName: [
{subcategory: 'jeans}',
],
},
];
and
#Injectable()
export class CategoriesService {
constructor() { }
getCategories(): Category[]{
return CATEGORIES;
}
}
I am trying to loop this data on my list
<ul>
<li *ngFor="let cat of categoryList">
{{cat.categoryName}}
<ul>
<li *ngFor="let subcat of categoryList">
asdad {{subcat.subcategory}}
</li>
</ul>
</li>
</ul>
For this I have added code in component .ts file
export class CategoriesComponent implements OnInit {
categoryList: Category[];
constructor(private categoryservice: CategoriesService) { }
ngOnInit() {
this.categoryList = this.categoryservice.getCategories();
}
}
Please help, I want to create a navbar list of categories, when upon hover it shows the relevant subcategory. Please let me know if you need additional information.
in the inner loop, you should loop over the inner array
<ul>
<li *ngFor="let cat of categoryList">
{{cat.categoryName}}
<ul>
<li *ngFor="let subcat of cat.subcatName">
asdad {{subcat.subcategory}}
</li>
</ul>
</li>
</ul>
Your inner loop should iterate over cat of the parent not categoryList
Change
From
<li *ngFor="let subcat of categoryList">
asdad {{subcat.subcategory}}
</li>
To
<li *ngFor="let subcat of cat.subcatName">
asdad {{subcat.subcategory}}
</li>