angularangular-componentsangular-component-router

Angular 6 child to Parent interaction through router outlet


I have app component with two child comoponent, namely first and second and I'm navigating through router outlet tag. I want to change parent component variable to 'XYZ' when I click on child component button.

app.component.html

<a routerLink = "/first">
  First
</a>
<a routerLink = "/second">
  Second
</a>
<div>
  <router-outlet></router-outlet>
</div>
{{myvar}}

app.component.ts

export class AppComponent {
  title = 'childParentInteraction';
  myvar : String = "ABCD";
}

app-routing.module.ts

const routes: Routes = [
  {
    path:"first", component: FirstComponent
  },
  {
    path:"second",component: SecondComponent
  }
];

first.component.html

<div>
    <p>first works!</p>
    <button (click)="changeVar()">
        Change variable
    </button>
</div>

first.component.ts

export class FirstComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  changeVar(){
  }
}

Solution

  • For this story:

    You should create a service which holds your variable.

    my-var.service.ts

    @Injectable({providedIn: 'root'})
    export class MyVarService {
      private myVar$ = new BehaviorSubject<any>(null);
      myVar: Observable<any> = this.myVar$.asObservable();
    
      setMyVar(newValue: any) {
        this.myVar$.next(newValue);
      }
    }
    

    FirstComponent: You need to inject and use setMyVar method of your service.

    fist.component.ts

    export class FirstComponent {
    
      constructor(private myVarService: MyVarService) {}
    
      setValue(value: any) {
        this.myVarService.setMyVar(value);
      }
    }
    

    AppComponent: You need to listen observable of myVar

    app.component.ts

    export class AppComponent implements OnInit, OnDestroy {
    
      myVar: any;
      destroyer$: Subject<void> = new Subject();
    
      constructor(private myVarService: MyVarService) {}
    
      ngOnInit() {
        this.myVarService.myVar.pipe(takeUntil(this.destroyer$)).subscribe(myVar => this.myVar = myVar);
      }
    
      ngOnDestroy() {
        this.destroyer$.next();
        this.destroyer$.complete();
      }
    }