Search code examples
angularangular-materialmodal-dialogangular-formsmat-dialog

How to pass data from modal to calling angular component?


callingmodal.component.ts

export class CallingmodalComponent implements OnInit {
    openDialog(): void {
        const dialogRef = this.dialog.open(SharemodalComponent, {
          width: '640px', disableClose: true
        });
        console.log(dialogRef);

      }
}

sharemodalComponent.component.ts

export class SharemodalComponent implements OnInit {
  onaddCus(): void {
    console.log(this.sharingWith);
    console.log(this.addCusForm.value.selectedPermissionType);
  }
}

Upon one button click, I call onaddCus(). In this function I want to pass this.sharingWith and this.addCusForm.value.selectedPermissionType to callingmodal.component.ts.

How do I pass this parameters to callingmodal.component.ts?


Solution

  • I assume you're dynamically creating sharemodalComponent from callingmodal. In that case, you could share data between them using a singleton service. Try the following

    shared.service.ts

    @Injectable({providedIn: 'root'})
    export class SharedService {
      private _sharingWithSource = new BehaviorSubject<any>(null);
      private _selectedPermissionTypeSource = new BehaviorSubject<any>(null);
      
      public sharingWith$ = this._sharingWithSource.asObservable();
      public selectedPermissionType$ = this._selectedPermissionTypeSource.asObservable();
    
      set sharingWithSource(value: any) {
        this._sharingWithSource.next(value);
      }
    
      set selectedPermissionTypeSource(value: any) {
        this._selectedPermissionTypeSource.next(value);
      }
    }
    

    sharemodalComponent.component.ts

    export class SharemodalComponent implements OnInit {
      constructor(private sharedService: SharedService) { }
      
      onaddCus(): void {
        this.sharedService.sharingWithSource = this.sharingWith;
        this.sharedService.selectedPermissionTypeSource = this.addCusForm.value.selectedPermissionType;
        console.log(this.sharingWith);
        console.log(this.addCusForm.value.selectedPermissionType);
      }
    }
    

    And in the calling modal component, subscribe in the ngOnInit hook to capture all the pushed notifications to the observables.

    callingmodal.component.ts

    export class CallingmodalComponent implements OnInit, OnDestroy {
      completed$ = new Subject<any>();
    
      constructor(private sharedService: SharedService) { }
    
      ngOnInit() {
        this.sharedService.sharingWith$.pipe(
          takeUntil(this.completed$)
        ).subscribe(
          value => {
            if (value) {           // <-- default value is `null`
              this.sharingWith = value 
            }
          }
        );
     
        this.sharedService.selectedPermissionType$.pipe(
          takeUntil(this.completed$)
        ).subscribe(
          value => {
            if (value) { 
              this.selectedPermissionType = value 
            }
          }
        );
      }
    
      openDialog(): void {
        const dialogRef = this.dialog.open(SharemodalComponent, {
          width: '640px', disableClose: true
        });
        console.log(dialogRef);
      }
    
      ngOnDestroy() {
        this.completed$.next();           // <-- close the observables
        this.completed$.complete();
      }
    }
    

    Update - explanation

    1. RxJS BehaviorSubject - A variant of the multicast observable RxJS Subject. It can hold the current data pushed to it and emit it immediately upon subscription. That is the reason it requires an initial value (we use null here) and we check before we assign the value.

    2. next method of the behavior subject is used to push a new value to the observable. Other valid methods to push notifications are error and complete. Pushing to error will invoke the error callback in the observer and calling complete will complete the observable stream.

    3. Whenever a subscription is involved, there is a potential memory leak from open/not-closed subscriptions. So it's always good practice to close the subscriptions in a component in it's OnDestroy hook. One way would be assign the subscription to a local variable and call unsubscribe() on it. Other elegant way is to use the RxJS takeUntil operator. More info about this approach here.

    4. Here is a good explanation from a core member of the RxJS team on when to use asObservable() function.