Search code examples
angulartypescriptbindingangular-dynamic-components

Angular 6 communicate between 2 components instances through service


I have a component that loads/remove another component dynamically by calling a service. I also give the dynamically add component the ability to remove itself. My problem is notifying the other component that this instance of the dynamic component is removed.

I have tried to use event output/emit and subject/subscribe without luck. Not sure if I'm doing it wrong.

Here is my code, once the button clicked and the component gets added, if I use the close button inside the component the main button doesn't know about that and it will require 2 clicks to toggle right, plus the text of the button will be wrong

https://stackblitz.com/edit/dynamically-row-components-for-smart-table

The problem I had when using the subject and subscribe it fires for all instances without efecting the button!


Solution

  • You can do a couple of things to make it work , instead of subscribing a common subject or event emitter for all component , create a unique subject dynamically for each component. So it won't fire for all components. For that first you need to is provide a unique componentName for each component or you can use the id.

    data = [
        {
          id: 1,
          name: 'Leanne Graham',
          username: 'Bret',
          email: 'Sincere@april.biz',
          button: 'Button #1',
          componentName:"component"+1
        }
    

    Step 2 : Register subjects for each row creation based the componentNae. On each close click the corresponding subscription will call and then you can remove the component from here

        ngOnInit() {
            this.renderValue = this.value.toString().toUpperCase();
             this.InjiService.componentSubjects[this.rowData.componentName] = new Subject();
             this.InjiService.componentSubjects[this.rowData.componentName].subscribe(()=>{
    
              this.InjiService.removeComponent(this.expanededComp);
              this.expanededComp = null;
              //this.renderValue = this.value.toString().toUpperCase(); //"Open";
              this.isOpen = false;
              //firing the change detection manually
              this.ref.markForCheck();    
            });
    
      }
    

    Please make sure you are declared the componentSubjects on your service

    export class InjiService {
     public componentSubjects: { [name: string]: Subject<any> } = {};
    

    Working sample