Como verificar o comprimento de uma matriz observável


108

No meu componente Angular 2, tenho uma matriz observável

list$: Observable<any[]>;

No meu modelo eu tenho

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

Mas list $ .length não funciona no caso de array Observable.

Atualizar:

Parece que (list $ | async) ?. length nos dá o comprimento, mas o código abaixo ainda não 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>

Alguém pode orientar como faço para verificar o comprimento da matriz Observable.


Respostas:


178

Você pode usar o | asynctubo:

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

Atualização - Versão Angular 6:

Se você estiver carregando um esqueleto css, poderá usá-lo. Se a matriz não tiver itens, ela exibirá o modelo css. Se houver dados, preencha o 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
Eu tentei isso também, mas dá o erro "TypeError: Não é possível ler a propriedade 'comprimento' de nulo"
— Naveed Ahmed

3
Difícil saber pelas informações que você forneceu. Experimente <div *ngIf="(list$ | async)?.length==0">No records found.</div>(adicionado ?)
— Günter Zöchbauer

6
Tentei fazer isso e funcionou <div * ngIf = "(list $ | async) ?. length == 0"> Nenhum registro encontrado. </div>
— Naveed Ahmed

3
O adicional ?é necessário porque list$só é definido depois que Angular2 tenta renderizar a visualização pela primeira vez. ?evita que o resto da subexpressão seja avaliado até que a parte à esquerda de ?se torne != null(Elvis ou operador de navegação segura).
— Günter Zöchbauer

1
@ GünterZöchbauer, parece-me que o primeiro asyncpipe resolve dados e, portanto, meu próximo asyncpipe no loop não exibe nada. Ou talvez *ngIfcrie um escopo adicional e, portanto, não esteja funcionando. Difícil dizer. Mas embora meu loop esteja dentro de if, ele não exibe nenhum dado. Se for avaliado truecorretamente.
— Eugene

31

Uma solução para arquivos .ts:

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

não é necessário cancelar a inscrição imediatamente depois?
— Peter,

É melhor cancelar a assinatura de observáveis ​​no onDestroycomponente
— ThPadelis

16

Para Angular 4+, experimente isto

<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

Embora esta resposta esteja correta

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

Lembre-se de que se estiver usando um cliente http para chamar backend (na maioria dos casos você faz), obterá chamadas duplicadas para sua API se tiver mais de uma lista $ | assíncrono . Isso ocorre porque cada | O pipe assíncrono criará um novo assinante para sua lista $ observable.


4

Isto é o que funcionou para mim -

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

Estou recebendo meus dados de httpClient async.

Todas as outras opções aqui não funcionaram para mim, o que foi decepcionante. Especialmente o cachimbo sexy (list $ | async).

Basa ..


2

Sua abordagem aqui tem outro grande problema: ao aproveitar o pipe assíncrono repetidamente em seu modelo, você está na verdade iniciando tantas assinaturas para o único Observable.

KAMRUL HASAN SHAHED tem a abordagem certa acima: use o pipe assíncrono uma vez e, em seguida, forneça um alias para o resultado que você pode aproveitar nos nós filhos.


1

Também pode ser reduzido:

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

Basta usar o ponto de exclamação antes do parêntese.


-3

iônico 4

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

funcionou quando eu removi o $sinal

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.