Cómo comprobar la longitud de una matriz observable


109

En mi componente Angular 2 tengo una matriz observable

list$: Observable<any[]>;

En mi plantilla tengo

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

Pero list $ .length no funciona en el caso de una matriz observable.

Actualizar:

Parece que (list $ | async) ?. length nos da la longitud, pero el siguiente código aún no funciona:

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

¿Alguien puede orientarme sobre cómo verificar la longitud de la matriz observable?


Respuestas:


178

Puedes usar la | asynctubería:

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

Actualización - Versión angular 6:

Si está cargando un esqueleto css, puede usar esto. Si la matriz no tiene elementos, mostrará la plantilla css. Si hay datos, complete el 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>

4
Lo intenté también, pero da el error "TypeError: No se puede leer la propiedad 'longitud' de nulo"
Naveed Ahmed

3
Es difícil saberlo por la información que proporcionó. Try <div *ngIf="(list$ | async)?.length==0">No records found.</div>(agregado ?)
Günter Zöchbauer

6
Intenté esto y funciona <div * ngIf = "(list $ | async) ?. length == 0"> No se encontraron registros. </div>
Naveed Ahmed

3
El adicional ?es obligatorio porque list$solo se establece después de que Angular2 intenta renderizar la vista por primera vez. ?impide que se evalúe el resto de la subexpresión hasta que la parte que queda a la izquierda se ?convierta en != null(Elvis u operador de navegación segura).
Günter Zöchbauer

1
@ GünterZöchbauer me parece que esa primera asynctubería resuelve datos y, por lo tanto, mi próxima asynctubería en el bucle no muestra nada. O tal vez *ngIfcrea un alcance adicional y, por lo tanto, no funciona. Difícil de decir. Pero mientras mi bucle está envuelto dentro, no muestra ningún dato. Si se evalúa truecorrectamente.
Eugene

31

Una solución para .ts-Files:

     this.list.subscribe(result => {console.log(result.length)});

¿No es necesario darse de baja inmediatamente después?
Peter

Es mejor darse de baja de los observables en el onDestroycomponente
ThPadelis

16

Para Angular 4+, prueba esto

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

7

Si bien esta respuesta es correcta

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

Tenga en cuenta que si está utilizando un cliente http para llamar al backend (en la mayoría de los casos lo hace), obtendrá llamadas duplicadas a su API si tiene más de una lista $ | async . Esto se debe a que cada | async pipe creará un nuevo suscriptor a su lista $ observable.


4

Esto es lo que funcionó para mí:

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

Obtengo mis datos de httpClient async.

Todas las otras opciones aquí no funcionaron para mí, lo cual fue decepcionante. Especialmente la tubería sexy (list $ | async).

Basa ..


2

Su enfoque aquí tiene otro problema importante: al aprovechar la tubería asíncrona una y otra vez en su plantilla, en realidad está iniciando tantas suscripciones al único Observable.

KAMRUL HASAN SHAHED tiene el enfoque correcto anterior: use la tubería asíncrona una vez y luego proporcione un alias para el resultado que puede aprovechar en los nodos secundarios.


1

También se puede acortar:

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

Simplemente use el signo de exclamación antes del paréntesis.


-3

iónico 4

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

funcionó cuando quité el $letrero

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.