Reputation: 1109
I’m working in an angular 6 application and I need a way to tell if my 2D observable array is empty or not.
Here’s my template:
<div *ngFor="let 1DArray of 2DArray$ | async">
<div *ngFor="let item of 1DArray">{{ item.id }}</div>
</div>
This gives me a list of ids.
Here’s my component code:
this.allItems$ = [];
source.forEach(obj => {
const colRef$ = this._firestoreService.colWithIds$(`Collection/${obj.id}/SubCollection`); // a collection of items
this.allItems$.push(colRef$); // an array of collections (2D array)
});
this.2DArray$ = Observable.combineLatest(this.allItems$); // an observable of the 2D array
This gives me an observable of the 2D array.
My problem is that if there are no items to retrieve from the firebase collection, the 2D array will not be empty. Instead, it will consist of a bunch of empty 1D arrays:
[
[],
[],
…
]
I’d like to put a label above the list of items on the page, something like “ITEMS:”. But if there are no items, I’d like to suppress this label.
I could do this by setting a flag, something like itemsExist: boolean. I’d set it like this:
this.itemsExist = false;
this.allItems$ = [];
source.forEach(obj => {
const colRef$ = this._firestoreService.colWithIds$(`Collection/${obj.id}/SubCollection`); // a collection of items
if (colRef$.length > 0) {
this.allItems$.push(colRef$); // an array of collections (2D Array)
this.itemsExist = true;
}
});
this.2DArray$ = Observable.combineLatest(this.allItems$); // an observable of the 2D array
…and then wrap the list in the template with a *ngIf:
<div *ngIf=“itemsExist”>
ITEMS:
<div *ngFor="let 1DArray of 2DArray$ | async">
<div *ngFor="let item of 1DArray">{{ item.id }}</div>
</div>
</div>
<div *ngIf=“!itemsExist”>
There are no items to display.
</div>
But I can’t use .length on an observable. There’s no way that I know of to check how many items exist on an array observable. Except, of course, if you subscribe to it. Then you just get the array and you can check it’s length. I tried something like that:
this.allItems$ = [];
source.forEach(obj => {
const colRef$ = this._firestoreService.colWithIds$(`Collection/${obj.id}/SubCollection`); // a collection of items
this.allItems$.push(colRef$); // an array of collections (2D array)
});
this.2DArray$ = Observable.combineLatest(this.allItems$); // an observable of the 2D array
this.itemCount = 0;
this.2DArray$.subscribe(item2DArray => {
item2DArray.forEach(item1DArray => {
this.itemCount += item1DArray.length;
});
});
Then I check itemCount in an *ngIf.
But then my list doesn’t show up at all even when there are items in it. I also tried subscribing to colRef$ and checking the length of the 1DArray, adding it to allItems$ only if it was greater than 0, but that had the same effect. Can an observable still be used in an *ngFor loop after it’s been subscribed to?
What way is there to check the length of an array observable?
Upvotes: 1
Views: 6183
Reputation: 1
the mat dataSource is a plain ol typescript object so i created a getter called getCount and in the dataSource have a member variable that exposes the response length. Then on the paginator i simple set the [length] to the dataSource.getCount().
Upvotes: 0
Reputation: 5470
You can achieve this with | async
pipe.
Example:
<div *ngIf="(2DArray$ | async)?.length !== 0">...</div>
Upvotes: 4