web-dev-qa-db-fra.com

Angular du tuyau et de l'objet asynchrones

J'ai besoin d'utiliser un pipe async sans ngFor. J'ai besoin de vérifier la propriété d'un objet chargé asynchrone avec observable.

C'est ce que je veux, mais ne fonctionne pas:

 <ion-item *ngIf="user$.anonymouse | async">
     <ion-label>Login</ion-label>
 </ion-item>

// EDIT: je reçois cette erreur quand j'utilise le code ci-dessus

EXCEPTION: l'argument non valide 'true' pour le tuyau 'AsyncPipe' dans [! User $ .anonymouse | async dans SettingsPage @ 27: 22]

Est-il possible de résoudre ce problème?

Je sais que je peux souscrire à cet observable dans Ctrl un magasin de valeurs en variable normale mais je ne veux pas le faire, à cause de la performance etc.

37
Daniel Suchý

L’erreur est étonnamment précise car la directive *ngIf S’attend à true ou false et utilise l’expression résultante pour déterminer s’il faut ou non rendre l’élément HTML dans l'élément. DOM.

EXCEPTION: l'argument non valide 'true' pour le tuyau 'AsyncPipe' dans [! User $ .anonymouse | async dans SettingsPage @ 27: 22]

L'expression que vous avez est user$.anonymouse, Qui est évaluée comme une vérité, mais vous ne pouvez malheureusement pas utiliser le tube async avec cette directive. Le async pipe "transforme" (également appelé "tuyaux") l'entrée qui expose la sortie résultante dans le cadre de la directive *ngFor Par exemple.

Le canal attend l'un des trois types possibles, définis ci-dessous ( détaillé sur AsyncPipe ):

transform(obj: Observable<any>| Promise<any>| EventEmitter<any>)

Est-il possible de résoudre ce problème?

Oui, vous pouvez l’utiliser tel qu’il a été conçu. Par exemple, dans une directive *ngFor:

<ion-item *ngFor="(user$ | async)?.anonymouse">
     <ion-label>Login</ion-label>
</ion-item>

Ou vous pouvez supprimer complètement la tuyauterie car elle n'est pas nécessaire pour la directive *ngIf:

<ion-item *ngIf="user$.anonymouse">
     <ion-label>Login</ion-label>
</ion-item>
28
David Pine

Comme indiqué dans les commentaires de @Sean, votre déclaration *ngIf Doit être basée sur la propriété d'objet obtenue anonymouse de l'objet user$ Renvoyé. En tant que tel:

<ion-item *ngIf="(user$ | async)?.anonymouse">
     <ion-label>Login</ion-label>
</ion-item>

Cela a fonctionné pour moi et voici un exemple d'utilisation des résultats du tuyau ci-dessous:

Composant

 message$: Observable<{message: string}>;

  private messages = [
    {message: 'You are my hero!'},
    {message: 'You are the best hero!'},
    {message: 'Will you be my hero?'}
  ];

  constructor() { this.resend(); }

  resend() {
    this.message$ = Observable.interval(500)
      .map(i => this.messages[i])
      .take(this.messages.length);
  }

Vue

<h2>Async Hero Message and AsyncPipe</h2>
<p>Message: {{ (message$ | async)?.message }}</p>
<button (click)="resend()">Resend</button>`

Un exemple de travail peut être trouvé ici .

45
Abdullah Rasheed

Je pense que cela pourrait aussi être utile:

<!-- This is needed to wait for async pipe to resolve -->
<div *ngIf="user$ | async as user"> 

   <!-- Only on resolve of async pipe -->
   <ion-item *ngIf="user.whateverPropertyYouWantToCheck">
        <ion-label>Login</ion-label>
    </ion-item>
</div>

Veuillez noter que je suis passé de user$ à user, vous pouvez utiliser le même nom de variable si vous le souhaitez, mais cela indique plus clairement qu'il ne s'agit plus d'un canal asynchrone.

7
TimNode