mohit tiwari
mohit tiwari

Reputation: 15

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(){
  }
}

Upvotes: 1

Views: 1396

Answers (3)

nevzatopcu
nevzatopcu

Reputation: 1085

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();
  }
}

Upvotes: 1

Rick
Rick

Reputation: 1870

you probably want an eventEmitter:

<router-outlet (messageEvent)="buttonClicked($event)"></router-outlet>

then on the child ts file:

add Output and EventEmitter to your import statement. add an @Output statement then add this.messageEvent.emit('pressed');

Upvotes: 0

Welyngton Dal Pra
Welyngton Dal Pra

Reputation: 774

Welcome to Stack Overflow!

There is a trick you can use in Angular 6:

By injecting the ViewContainerRef on children components:

constructor(private viewContainerRef: ViewContainerRef) { }

And than you can access like this:

getParentComponent() {
  return this.viewContainerRef[ '_data' ].componentView.component.viewContainerRef[ 
   '_view' ].component
  }

  this.getParentComponent().myvar = "XYZ"

Upvotes: 0

Related Questions