Search code examples
angularangular-materialmaterial-dialog

How to refresh Angular Mat-Table adding Data with Angular dialog


I would like to refresh the items a mat table after adding one item.But in my table not updating with dialog module.I have tried,calling my list component in my products component by viewchild but,I can't update table.Without using dialog module,my mat-table can be update but with dialog cannot be update my table.

How can I solve it?

Create Component:

export class CreateComponent extends BaseComponent implements OnInit {
  userAddressValidations: FormGroup;
  constructor(private formBuilder: FormBuilder,spiner: NgxSpinnerService, private productService: ProductService, private alertify: AlertifyService) {
    super(spiner)
  }
  
  ngOnInit(): void {
    this.userAddressValidations = this.formBuilder.group({
      name: ['', [Validators.required, Validators.minLength(5), Validators.maxLength(50), Validators.pattern('^[a-zA-Z ]*$')]],
      stock: ['', [Validators.required],Validators.min(0)],
      price: ['', [Validators.required],Validators.min(0)],
    
    });
  }

  @Output() createdProduct: EventEmitter<Create_Product> = new EventEmitter();

  create(name: HTMLInputElement, stock: HTMLInputElement, price: HTMLInputElement) {
    this.showSpinner(SpinnerType.BallAtom);
    const create_product: Create_Product = new Create_Product();
    create_product.name = name.value;
    create_product.stock = parseInt(stock.value);
    create_product.price = parseFloat(price.value);

    this.productService.create(create_product, () => {
      this.hideSpinner(SpinnerType.BallAtom);
      this.alertify.message("Ürün başarıyla eklenmiştir.", {
        dismissOthers: true,
        messageType: MessageType.Success,
        position: Position.TopRight
      });
      this.createdProduct.emit(create_product);
      
    }, errorMessage => {
      this.alertify.message(errorMessage,
        {
          dismissOthers: true,
          messageType: MessageType.Error,
          position: Position.TopRight
        });
    });
  }
}

dialog service:

export class DialogService {

  constructor(private dialog: MatDialog) { }
  

  openDialog(dialogParameters: Partial<DialogParameters>): void {
    const dialogRef = this.dialog.open(dialogParameters.componentType, {
      width: dialogParameters.options?.width,
      height: dialogParameters.options?.height,
      position: dialogParameters.options?.position,
      data: dialogParameters.data,
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result == dialogParameters.data)
        dialogParameters.afterClosed();
    });
  }

  
}

export class DialogParameters {
  componentType: ComponentType<any>;
  data: any;
  afterClosed: () => void;
  options?: Partial<DialogOptions> = new DialogOptions();
}

export class DialogOptions {
  width?: string = "250px";
  height?: string;
  position?: DialogPosition;
}

Products Component:

export class ProductsComponent extends BaseComponent implements OnInit {

  constructor(spinner: NgxSpinnerService, private httpClientService: HttpClientService, private dialogService: DialogService,private dialog:MatDialog) {
    super(spinner)
  }

  createProduct() {
    
    this.dialogService.openDialog({

      componentType: CreateComponent,
      data: null,
      options: {
        width: "500px"
      },
      afterClosed: () => { }
    },
    );
    
  }

  ngOnInit(): void {
   
  }
}

Html

<button style="margin:15px;font-size: 17px;text-align: center;align-content: center;" mat-raised-button class="btn" color="primary" (click)="createProduct()">



   @ViewChild(ListComponent) listComponents: ListComponent;

   createdProduct(createdProduct: Create_Product) {
    this.listComponents.getProducts();
     console.log(this.listComponents);
   }

Solution

  • When you open the dialog, pass a callback function inside the data property, this will call the viewChild. We use bind(this) when we pass the function, this will ensure the function is executed in the source component context (where view child exists).

    refresh() { this.listComponents.getProducts(); }
    
    this.dialogService.openDialog({
    
      componentType: CreateComponent,
      data: { callback: this.refresh.bind(this) },
      options: {
        width: "500px"
      },
      afterClosed: () => { }
    },
    ); 
    

    Then we access the config through the data as shown below.

    constructor(
     ...
     @Inject(MAT_DIALOG_DATA) public data,
     ...
    ) { }
    
    create(name: HTMLInputElement, stock: HTMLInputElement, price: HTMLInputElement) {
        ...
        this.productService.create(create_product, () => {
          ...
          if(data.callback) {
              data.callback();
          }
          ...