2
votes

Pour fermer le composant de dialogue en fonction de la réponse de l'API

J'ai un composant appelé AddCustomerComponent que j'appelle comme composant de dialogue, Dans le AddCustomerComponent après avoir rempli les champs de saisie, j'effectue l'opération POST .Now POST fonctionne correctement.

Mais après l'opération POST basée sur la réponse de l'API, je souhaite effectuer les opérations suivantes:

  • Si le POST réussit, la boîte de dialogue (AddCustomerComponent) doit se fermer.
  • Sinon, la boîte de dialogue ne doit pas se fermer.

Voici mon code de composant et mes codes de fichier de service :

HTML

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ICustomer } from 'src/app/models/app.models';

@Injectable({
  providedIn: 'root',
})

export class CustomersService {
 private  baseUrl : string = '....api URL.....';

 constructor(private http: HttpClient) {}

  public async addCustomer(customer: ICustomer ): Promise<void>  {
    const apiUrl: string = `${this.baseUrl}/customers`;
    let temp : any;
    temp =  this.http.post(apiUrl, customer).subscribe(data => {
        alert('Customer added successfully');
    },error => {
        console.log(error);
    });
  }

}

TS[

import { Component, OnInit } from '@angular/core';
import {
  FormBuilder,
  FormGroup,
  Validators,
} from '@angular/forms';
import { MatDialog, MatDialogRef } from '@angular/material';
import { ICustomer } from 'src/app/models/app.models';
import { CustomersService } from 'src/app/services/customers.service';

@Component({
  selector: 'awa-add-customer',
  templateUrl: './add-customer.component.html',
  styleUrls: ['./add-customer.component.css'],
})
export class AddCustomerComponent implements OnInit {
  public addForm: FormGroup;
  public someCustomer: ICustomer;

  constructor(
    private fb: FormBuilder,
    public dialog: MatDialog,
    public customersService: CustomersService,
  ) {}

  public ngOnInit(): void {
    this.addForm = this.fb.group({
      name: [null,[Validators.required]],
      email: [null,[Validators.required]],
    });
  }

  public onAddCustomer(): void {
    this.someCustomer = this.addForm.value;
    this.customersService.addCustomer(this.someCustomer);
  }

}

Service Fle

<form [formGroup]="addForm">
    <mat-form-field>
        <input matInput placeholder="Name" formControlName="name" required>
        <mat-error *ngIf="addCusForm.controls.name.hasError('required')">
            Please enter your name
        </mat-error>
    </mat-form-field>
    <mat-form-field>
        <input placeholder="Email Address"  formControlName="email" required>
        <mat-error *ngIf="addCusForm.controls.email.hasError('required') ">
            Please enter email address
        </mat-error>
    </mat-form-field>
    <button mat-flat-button  type="submit" (click)="onAddCustomer()">Save</button>
    <button mat-flat-button  type="button">Cancel</button>  
</form>


2 commentaires

renvoyer la promesse du service et gérer la réponse / erreur dans votre composant avec then () , catch ()


Pourquoi définissez-vous toutes les méthodes comme publiques?


4 Réponses :


2
votes

Vous devez fermer la référence de la boîte de dialogue. Je pense que l'observable est un bon choix. Votre service pourrait ressembler à ceci.

import { Component, OnInit } from '@angular/core';
import {
  FormBuilder,
  FormGroup,
  Validators,
} from '@angular/forms';
import { MatDialog, MatDialogRef } from '@angular/material';
import { ICustomer } from 'src/app/models/app.models';
import { CustomersService } from 'src/app/services/customers.service';

@Component({
  selector: 'awa-add-customer',
  templateUrl: './add-customer.component.html',
  styleUrls: ['./add-customer.component.css'],
})
export class AddCustomerComponent implements OnInit {
  public addForm: FormGroup;
  public someCustomer: ICustomer;

  constructor(
    private fb: FormBuilder,
    public dialog: MatDialog,
    public dialogRef: MatDialogRef<AddCustomerComponent>
    public customersService: CustomersService,
  ) {}

  public ngOnInit(): void {
    this.addForm = this.fb.group({
      name: [null,[Validators.required]],
      email: [null,[Validators.required]],
    });
  }

  public onAddCustomer(): void {
    this.someCustomer = this.addForm.value;


  this.customersService.addCustomer(this.someCustomer).subscribe((respons)=>{
   // validate the response here and then close the dialog
    // after successfull adding customer
    this.dialogRef.close();
    });

  }

}

Votre composant ressemblera à ceci.

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ICustomer } from 'src/app/models/app.models';
import { Observable} from 'rxjs';

@Injectable({
  providedIn: 'root',
})

export class CustomersService {
 private  baseUrl : string = '....api URL.....';

 constructor(private http: HttpClient) {}

  public async addCustomer(customer: ICustomer ): Observable<any>  {
    const apiUrl: string = `${this.baseUrl}/customers`;
    let temp : any;
    return this.http.post(apiUrl, customer);
  }

}


2 commentaires

Veuillez lire ma question complètement, je veux fermer la boîte de dialogue en fonction de la réponse de l'API , je sais comment fermer la boîte de dialogue en cliquant sur le bouton .


Ok, laissez-moi essayer.



1
votes

vous devez travailler avec la promesse renvoyée par le service.

public onAddCustomer(): void {
this.someCustomer = this.addForm.value;
this.customersService.addCustomer(this.someCustomer)
  .then(
    // add success code here
  )
  .catch(
    // add error code here
  )

}


0 commentaires

1
votes

Ici, au lieu de vous abonner à un fichier de service, abonnez-vous à votre composant afin de pouvoir appliquer vos conditions comme ci-dessous.

Service.ts

 public onAddCustomer(): void {
    this.someCustomer = this.addForm.value;
    this.customersService.addCustomer(this.someCustomer).subscribe(data => {
        alert('Customer added successfully');
        this.dialogRef.close();
    },error => {
    // do not close dialog when error.
        console.log(error);
    });
  }


0 commentaires

2
votes

Il vous suffit de renvoyer la promesse de l'appel Post de votre service, et de vous y abonner pour fermer la boîte de dialogue que l'appel http se soit bien passé ou non.

D'abord, n'oubliez pas de renvoyer votre promesse dans la méthode de service:

public onAddCustomer(): void {
  this.someCustomer = this.addForm.value;
  this.customersService.addCustomer(this.someCustomer).subscribe(
    () => // POST is ok, close dialog,
    (error) => // do nothing, or alert
  );
}

Ensuite, abonnez-vous à la promesse en appelant la méthode addCustomer () :

public addCustomer(customer: ICustomer ): Promise<void>  {
  const apiUrl: string = `${this.baseUrl}/customers`;
  return this.http.post(apiUrl, customer);
  // I removed the subscribe() here since you can have only one per promise
  // But you can use Rxjs 'pipe' operation if necessary.
}


2 commentaires

Votre solution fonctionne bien, merci pour les ans, mais si j'ajoute Promise dans la méthode addCustomer dans le service file.it montrant cette charpie erreur: [ts] Le type 'Observable ' ne contient pas les propriétés suivantes du type 'Promise ': puis, catch, [Symbol.toStringTag]


J'ai supprimé le mot-clé async de votre méthode, car vous n'avez pas utilisé await lors de son appel. async renvoie automatiquement une Promise, maintenant vous retournez un Observable :) Si vous préférez utiliser Promises, vous devriez essayer d'appeler this.http.post (.. .). toPromise () .