Proper way to call modal dialog from another component in Angular?

Viewed 4446

I have a component called department where I create a department using a modal dialog as shown below:

department.component

openModal(data) {
    //code omitted for simplicity
    this.modalService.showMOdal();
    this.create();
}

create() {
    //code omitted for simplicity
}

employee.component

createDepartment() {
    //???
}

On the other hand, I have another component called employee and I need to create a departmet by calling the open dialog and create methods in the department component.

What is the proper way to create department from employee component? Should I implement openModal() and create() methods in employee component as well? Or should I call the methods that are already defined in department component? I think it sould be better to use already existing methods and components in order to avoid from repetition.

Any example approach for this scenario?

2 Answers

Extract this data logic from components and move it to a separate service.

// Move functions for opening the modal from DepartmentComponent to a service
@Injectable({providedIn: 'root'})
export class DepartmentService {
  constructor(private modalService: ModalService){}

  openModal(data) {...}

  create() {...}
}

// Inject the service into EmployeeComponent
export class EmployeeComponent {
  constructur(private departmentService: DepartmentService){}

  createDepartment() {
    this.departmentService.openModal()/create();  // whichever you actually need to call (should probably only be one that delegates to other functions)
  }
}

EDIT:
With some more information, a specific form (for creating a department) is meant to be displayed in more than one place in the app (in a modal and an employee component).

For this, create a component that holds the form (with create button etc) and the required event handlers (e.g. create department button) and display that where needed (the actual logic for creating the department should be in a separate service).

E.g. in the employee html

... employee information ...
<app-createdepartment></app-createdepartment>

And the modal should be something like this (component might have to be in EntryComponents, depending on angular version):

let dialogRef = dialog.open(CreateDepartmentComponent, {
  height: '400px',
  width: '600px',
});

(Docs for MatDialog: https://material.angular.io/components/dialog/overview)

<button type="button" (click)="addCampaignProduct()" mat-raised-button color="primary"
[title]="'ADD_CAMPAIGN_PRODUCT' | translate:lang">
<i class="material-icons">add_circle</i>{{ 'ADD_CAMPAIGN_PRODUCT' | translate:lang }}
</button>

export class CampaignConfigurableProductsComponent implements OnInit, AfterViewInit { }


    addCampaignProduct() {
        const dialogRef = this.dialog.open(AddConfigurableProductComponent, {
            disableClose: true,
            data: { campaignId: this.params.id }
        })
        dialogRef.afterClosed().subscribe(() => {
          this.ngOnInit()
        });
    }

export class AddConfigurableProductComponent implements OnInit { 


 addProduct() {
    const selectedOrderIds = this.addProductForm.value.colors
      .map((checked, i) => checked ? this.colorAttributeData[i].config_product_option_value : null)
      .filter(v => v !== null);

    if (this.addProductForm.value.actual_price == '') {
      this.sales_price = this.addProductObj.recommended_price;
    } else {
      this.sales_price = this.addProductForm.value.actual_price;
    }
    this.addProductObj['sales_price'] = this.sales_price;
    this.addProductObj['actual_price'] = this.finalPriceValue;
    this.addProductObj['campaign_id'] = this.data.campaignId;

this.campaignService.addProductCatalog(this.addProductObj).subscribe((response: any) => {
      if (response) { 

      }
  }, (error) => {
      this.notify.error('Something went wrong')
      console.log(error)
    })
}



}

Related