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.