Comment vérifier la longueur d'un tableau observable

109

Dans mon composant Angular 2, j'ai un tableau observable

list$: Observable<any[]>;

Dans mon modèle j'ai

<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>

Mais la liste $ .length ne fonctionne pas avec dans le cas d'un tableau Observable.

Mettre à jour:

Il semble que (list $ | async)?. Length nous donne la longueur mais le code ci-dessous ne fonctionne toujours pas:

<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>

Quelqu'un peut-il s'il vous plaît guider comment vérifier la longueur du tableau observable.

Naveed Ahmed
la source
Signalé sur github.com/angular/angular/issues/9641
Günter Zöchbauer

Réponses:

179

Vous pouvez utiliser le | asynctuyau:

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

Mise à jour - Angular Version 6:

Si vous chargez un squelette css, vous pouvez l'utiliser. Si le tableau ne contient aucun élément, il affichera le modèle css. S'il y a des données, remplissez le 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
la source
4
J'ai essayé cela aussi mais cela donne l'erreur "TypeError: Cannot read property 'length' of null"
Naveed Ahmed
3
Difficile à savoir d'après les informations que vous avez fournies. Try <div *ngIf="(list$ | async)?.length==0">No records found.</div>(ajouté ?)
Günter Zöchbauer
6
J'ai essayé et cela fonctionne <div * ngIf = "(list $ | async) ?. length == 0"> Aucun enregistrement trouvé. </div>
Naveed Ahmed
3
Le supplément ?est requis car il list$n'est défini qu'après qu'Angular2 essaie de rendre la vue la première fois. ?empêche le reste de la sous-expression d'être évalué jusqu'à ce que la partie à gauche de ?devienne != null(Elvis ou opérateur de navigation sûre).
Günter Zöchbauer
1
@ GünterZöchbauer il me semble que ce premier asynctube résout les données et donc mon prochain asynctube en boucle n'affiche rien. Ou peut-être *ngIfcrée une portée supplémentaire et donc cela ne fonctionne pas. Dur à dire. Mais alors que ma boucle est enveloppée à l'intérieur de if, elle n'affiche aucune donnée. Si lui-même évalue truecorrectement.
Eugene
31

Une solution pour .ts-Files:

     this.list.subscribe(result => {console.log(result.length)});
Vide
la source
n'est-il pas nécessaire de se désinscrire immédiatement après?
Peter
Il est préférable de se désabonner des observables sur le onDestroycomposant
ThPadelis
16

Pour Angular 4+, essayez ceci

<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
la source
7

Bien que cette réponse soit correcte

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

Gardez à l'esprit que si vous utilisez le client http pour appeler le backend (dans la plupart des cas, vous le faites), vous obtiendrez des appels en double vers votre API si vous avez plus d'une liste $ | asynchrone . C'est parce que chaque | async pipe créera un nouvel abonné à votre liste $ observable.

Andzej Maciusovic
la source
4

C'est ce qui a fonctionné pour moi -

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

Je récupère mes données depuis httpClient async.

Toutes les autres options ici ne fonctionnaient pas pour moi, ce qui était décevant. Surtout le tube sexy (list $ | async).

Basa ..

Tzvi Gregory Kaidanov
la source
2

Votre approche ici présente un autre problème majeur: en exploitant le canal asynchrone à plusieurs reprises dans votre modèle, vous lancez en fait autant d'abonnements à l'unique Observable.

KAMRUL HASAN SHAHED a la bonne approche ci-dessus: utilisez le tube asynchrone une fois, puis fournissez un alias pour le résultat que vous pouvez exploiter dans les nœuds enfants.

Harry Beckwith
la source
1

Peut également être raccourci:

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

Utilisez simplement le point d'exclamation avant la parenthèse.

Daniyal Lukmanov
la source
-3

ionique 4

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

cela a fonctionné quand j'ai enlevé le $signe

Ahmed Al-hajri
la source