So überprüfen Sie die Länge eines Observable-Arrays

107

In meiner Angular 2-Komponente habe ich ein Observable-Array

list$: Observable<any[]>;

In meiner Vorlage habe ich

<div *ngIf="list$.length==0">No records found.</div>

<div *ngIf="list$.length>0">
    <ul>
        <li *ngFor="let item of list$ | async">item.name</li>
    </ul>
</div>

Die Liste $ .length funktioniert jedoch bei einem Observable-Array nicht.

Aktualisieren:

Es scheint, dass (Liste $ | async)?. Länge gibt uns die Länge, aber der folgende Code funktioniert immer noch nicht:

<div>
    Length: {{(list$ | async)?.length}}
    <div *ngIf="(list$ | async)?.length>0">
        <ul>
            <li *ngFor="let item of (list$ | async)">
                {{item.firstName}}
            </li>
        </ul>
    </div>
</div>

Kann mir jemand bitte zeigen, wie ich die Länge des Observable-Arrays überprüfe?

Naveed Ahmed
quelle
Berichtet bei github.com/angular/angular/issues/9641
Günter Zöchbauer

Antworten:

178

Sie können das | asyncRohr verwenden:

<div *ngIf="(list$ | async)?.length==0">No records found.</div>

Update - Angular Version 6:

Wenn Sie ein CSS-Skelett laden, können Sie dies verwenden. Wenn das Array keine Elemente enthält, wird die CSS-Vorlage angezeigt. Wenn Daten vorhanden sind, füllen Sie die aus ngFor.

<ul *ngIf="(list$| async)?.length > 0; else loading">
   <li *ngFor="let listItem of list$| async">
      {{ listItem.text }}
   </li>
</ul>

<ng-template #loading>
  <p>Shows when no data, waiting for Api</p>
  <loading-component></loading-component>
</ng-template>
Günter Zöchbauer
quelle
4
Ich habe das auch versucht, aber es gibt den Fehler "TypeError: Eigenschaft 'Länge' von null kann nicht gelesen werden"
Naveed Ahmed
3
Aus den von Ihnen angegebenen Informationen schwer zu erkennen. Versuchen Sie <div *ngIf="(list$ | async)?.length==0">No records found.</div>(hinzugefügt ?)
Günter Zöchbauer
6
Ich habe es versucht und es funktioniert <div * ngIf = "(Liste $ | async)?. Länge == 0"> Keine Datensätze gefunden. </ Div>
Naveed Ahmed
3
Das zusätzliche ?ist erforderlich, da list$es erst festgelegt wird, nachdem Angular2 versucht, die Ansicht zum ersten Mal zu rendern. ?verhindert , dass der Rest des Unter Ausdruck ausgewertet werden , bis der Teil links ?wird != null(Elvis oder safe-Navigationsführung).
Günter Zöchbauer
1
@ GünterZöchbauer es scheint mir, dass die erste asyncPipe Daten auflöst und daher meine nächste asyncPipe-on-Schleife nichts anzeigt. Oder *ngIfschafft vielleicht einen zusätzlichen Bereich und deshalb funktioniert es nicht. Schwer zu erzählen. Aber während meine Schleife in if eingeschlossen ist, werden keine Daten angezeigt. Wenn selbst truerichtig auswertet .
Eugene
32

Eine Lösung für .ts-Files:

     this.list.subscribe(result => {console.log(result.length)});
Leer
quelle
ist es nicht notwendig, sich danach sofort abzumelden?
Peter
Es ist besser, sich von Observables auf onDestroyKomponente
abzumelden
16

Versuchen Sie dies für Angular 4+

<div *ngIf="list$ | async;let list">
    Length: {{list.length}}
    <div *ngIf="list.length>0">
        <ul>
            <li *ngFor="let item of list">
                {{item.firstName}}
            </li>
        </ul>
    </div>
</div>
MD KAMRUL HASAN SHAHED
quelle
7

Während diese Antwort richtig ist

<div *ngIf="(list$ | async)?.length === 0">No records found.</div>

Beachten Sie, dass Sie, wenn Sie den http-Client zum Aufrufen des Backends verwenden (in den meisten Fällen), doppelte Aufrufe an Ihre API erhalten, wenn Sie mehr als eine Liste $ | haben asynchron . Dies liegt daran, dass jeder | Async Pipe erstellt einen neuen Abonnenten für Ihre Liste $ beobachtbar.

Andzej Maciusovic
quelle
4

Das hat bei mir funktioniert -

*ngIf="!photos || photos?.length===0"

Ich erhalte meine Daten von httpClient async.

Alle anderen Optionen hier haben bei mir nicht funktioniert, was enttäuschend war. Besonders die sexy (Liste $ | async) Pfeife.

Basa ..

Tzvi Gregory Kaidanov
quelle
2

Ihr Ansatz hier hat ein weiteres großes Problem: Indem Sie die asynchrone Pipe in Ihrer Vorlage immer wieder nutzen, starten Sie tatsächlich so viele Abonnements für das einzelne Observable.

KAMRUL HASAN SHAHED hat oben den richtigen Ansatz: Verwenden Sie die asynchrone Pipe einmal und geben Sie dann einen Alias ​​für das Ergebnis an, das Sie in untergeordneten Knoten nutzen können.

Harry Beckwith
quelle
1

Kann auch gekürzt werden:

<div *ngIf="!(list$ | async)?.length">No records found.</div>

Verwenden Sie einfach das Ausrufezeichen vor der Klammer.

Daniyal Lukmanov
quelle
-2

ionisch 4

<div *ngIf="(items | async)?.length==0">No records found.</div>

Es hat funktioniert, als ich das $Schild entfernt habe

Ahmed Al-hajri
quelle