J'ai essayé d'utiliser async / await pour éviter *ngIf dans le modèle de composant.

J'obtiens une erreur dans la console Chrome lorsque je supprime *ngIf dans le modèle de composant.

Quelqu'un peut-il aider à trouver une solution. Je ne souhaite pas utiliser *ngIf dans le modèle de composant comme exigence

J'appelle l'API GET REST et j'utilise l'abonnement. De plus, j'obtiens des résultats sans erreur si j'utilise *ngIf, mais je veux les mêmes résultats sans utiliser *ngIf

CODE: component.ts

export class DisplayComponent implements OnInit {
users : user[];
user: user;
userResult: any;

  constructor(private http: HttpClient) { }

  ngOnInit() {
  }


  async readUser(id){
     this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).subscribe(
       data => {
         this.user = data;
       },
       error =>{
         return console.error();
         ;
       }
     )
    console.log("Fuuhhh! Client will wait till promise is resolved.");
  }
}

CODE: DisplayComponent.html

<div style="text-align: center;">
    <button (click)="loadUsers()">load Users</button>
    <table style="margin: 0 auto;" border="1">
        <tr>
            <th>Identity</th>
        </tr>
        <tr *ngFor="let user of users">
           <td>
            <button style="background: transparent;border: transparent;cursor: pointer;" (click)="readUser(user.id)">{{user?.id}}</button>
            </td>
        </tr>
    </table>

</div>
<div style="text-align: center;">
    <span style="color: darkgray;">Identity:</span> <span style="color: gray;">{{user.id}}</span> <br>
    <span>Name:</span> {{user.name}} <br> 
    <span>School:</span> {{user.school}} <br> 
</div>
-1
Chintan Raval 30 mai 2020 à 13:21

4 réponses

Je pense que vous devez utiliser le ngIf parce que votre modèle se charge avant d'obtenir vos données. Votre HTML est donc prêt à recevoir les données. Ce que vous pouvez faire, et c'est plus propre, est de créer une variable booléenne:

isDataReady: Boolean = false;

Ensuite, dans votre html, utilisez-le simplement car il sera toujours faux jusqu'à ce que vous le changiez dans votre composant lorsque l'abonnement obtiendra les données.

De plus, dans mes projets, j'utilise un spinner de matériau angulaire, pour informer l'utilisateur de son chargement des données back-end avec cette variable que j'ai créée.

J'espère que cela aide!

0
Pau 30 mai 2020 à 10:40

Le code que vous avez pour stocker le userResult n'est pas une promesse, est un abonnement:

async readUser(id){
     // this block is wrong, userResult is a subscription
     this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).subscribe(
       data => {
         this.user = data;
       },
       error =>{
         return console.error();
         ;
       }
     )
    console.log("Fuuhhh! Client will wait till promise is resolved.");
  }

Si vous voulez utiliser des promesses (mais vous devriez vous observer dans Angular), vous pouvez le faire en utilisant la méthode toPromise() comme ceci:

async readUser(id){
     try {
       this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).toPromise();
       this.user = this.userResult // if you really want an extra step here
    } catch(error) {
      console.log(error);
    }
  }

Concernant votre question, vous devriez utiliser *ngIf pour ce cas.

Pour les blocs de code, utilisez-le avec ng-container comme ceci:

<ng-container *ngIf="user">
   .....
</ng-container>
0
ionut-t 30 mai 2020 à 11:11

Angular a un système de cycle de vie, donc Angular essaie de charger le composant avant d'obtenir les données de votre API. Alors oui, vous devez gérer le cas avant que l'API ne réponde.

Vous avez 2 façons de le faire:

  • utilisez * ngIf mais vous n'êtes pas obligé d'utiliser * ngIf partout si vous faites beaucoup d'appels si c'est votre peur, vous pouvez utiliser ngrx correctement et utiliser un * ngIf uniquement dans votre HTML

  • initialisez vos données avec la valeur par défaut. Angular chargera votre utilisateur "par défaut" et le remplacera par l'utilisateur reçu par l'API, s'il n'y a pas d'erreur bien sûr. Si vous voulez vraiment l'utiliser, essayez un

user: user = new user();

Et bien sûr, initialisez tous les attributs que vous utilisez par une chaîne vide, ... dans le constructeur utilisateur.

Mais je pense que la première façon est meilleure car vous pouvez gérer l'erreur et le cas d'attente plus correctement avec un spinner de chargement, un message de chargement et d'erreur, ... MAIS vous devez apprendre les bases de rxjs :)

0
Gauthier T. 30 mai 2020 à 11:07

Je pense que vous n'utilisez pas le * ngIf de la bonne manière.Tout ce que vous avez à faire est d'ajouter un * ngIf dans votre modèle comme suit, vous n'avez pas besoin d'ajouter plusieurs * ngIf pour chaque balise.

<div style="text-align: center;" *ngIf="user">
    <span style="color: darkgray;">Identity:</span> <span style="color: gray;">{{user.id}}</span> <br>
    <span>Name:</span> {{user.name}} <br> 
    <span>School:</span> {{user.school}} <br> 
</div>
0
Shijil Narayanan 30 mai 2020 à 10:53