Empty_Soul
Empty_Soul

Reputation: 809

To close dialog component based on api response

I have component called AddCustomerComponent which i am calling as dialog component,In the AddCustomerComponent after filling the input fields i am performing POST operation.Now POST operation working fine.

But after POST operation based on the api response, I want perform following operations:

Below are my component code and service file codes:

HTML

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

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

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);
    });
  }

}

Upvotes: 2

Views: 6797

Answers (4)

Kapcash
Kapcash

Reputation: 6919

You simply have to return the promise of the Post call from your service, and subscribe to it to close the dialog wheter or not the http call has gone well.

First, don't forget to return your promise in the service method:

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

Then, subscribe to the promise when calling the addCustomer() method:

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

EDIT: The previous snippet has been deprecated and will be removed in RxJS v8. Docs: https://rxjs.dev/deprecations/subscribe-arguments The new suggested method is to use an object parameter to specify which callback to use.

public onAddCustomer(): void {
   this.someCustomer = this.addForm.value;
   this.customersService.addCustomer(this.someCustomer).subscribe({
      next: (v) => console.log(v),
      error: (e) => console.error(e),
      complete: () => console.info('complete') 
   });
}

If you only use the next callback, it is recommended to simply pass in an anonymous function:

public onAddCustomer(): void {
   this.someCustomer = this.addForm.value;
   this.customersService.addCustomer(this.someCustomer).subscribe((v) => console.log(v));
}

Upvotes: 3

TheParam
TheParam

Reputation: 10561

Here instead of subscribing in a service file, subscribe in your component so that you can apply your conditions like below.

Service.ts

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

component.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);
    });
  }

Hope this help!

Upvotes: 1

Naieem Mahmud Supto
Naieem Mahmud Supto

Reputation: 188

You have to close the dialog reference.I think observable is a good choice. You service could be like this.

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);
  }

}

Your component will look like this.

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();
    });

  }

}

Upvotes: 2

bqwekaf
bqwekaf

Reputation: 11

you should work with the promise returned from the service.

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

}

Upvotes: 1

Related Questions