Nate
Nate

Reputation: 7856

Access router outlet component from parent

I have the following app root:

@Component({
    selector: 'my-app',
    providers: [],
    templateUrl: `<button (click)="callChildFunction()">Close</button>
                  <router-outlet></router-outlet>`
})
export class AppComponent {

    constructor() {

    }

    callChildFunction(){
        // Call myFunction() here
    }

}

And here is my child (component used in the router-outlet):

@Component({
    selector: 'child',
    providers: [],
    templateUrl: `<div>Hello World</div>`
})
export class ChildComponent {

    constructor() {

    }

    myFunction(){
        console.log('success');
    }

}

I have discovered that I can use RouterOutlet to get the component functions but it doesn't seem accessible from within the app root.

How can I call myFunction() from the app root?

Upvotes: 22

Views: 15047

Answers (4)

Sinh Nguyễn Đức
Sinh Nguyễn Đức

Reputation: 711

For more infomation, you can access the variable of ChildComponent as well.

Child Comp

export class ChildComponent {
    my_var= true;
}   

Parent Component

// Template

<div class="container">
    <router-outlet (activate)="onActivate($event)"></router-outlet>
  </div>


  onActivate(componentRef){
    console.log(componentRef.my_var);
  }

Upvotes: 0

Oliver
Oliver

Reputation: 1269

A small addition to @Rahul Singh great answer:

Make sure you check, which component instance is returned in the
(staying at Rahul's example) onActivate(componentRef) method,
and only call works(), if that component indeed has such method.

Example:

     onActivate(componentRef){
       if(componentRef instanceof ChildWithWorksMethodComponent){
         componentRef.works();
         return;
         }
         console.log("This is not the ChildWithWorksMethodComponent");
      }  

Otherwise, every time you navigate to a route, which component doesn't have such method, your console log will be full of errors like:

ERROR TypeError: componentRef.works is not a function

Upvotes: 7

Rahul Singh
Rahul Singh

Reputation: 19622

Make use of activate event for the same . Whenever we load a component in router outlet a activate event is emitted make use of that to get the component ref and call the respective method.

Parent Component

  <div class="container">
    <router-outlet (activate)="onActivate($event)"></router-outlet>
  </div>

Template

  onActivate(componentRef){
    componentRef.works();
  }

Child Comp

 works(){
    console.log("works");
  }

Upvotes: 40

Vikhyath Maiya
Vikhyath Maiya

Reputation: 3192

Router-outlet is related to routing it has nothing to do with accessing the child component methods.You have to use @ViewChild for accessing child component functions from the parent.You can find the example here

update

If above isn't a feasible solution in your case,you may tap into activate event to get reference of instantiated component inside the router outlet.

From the docs

A router outlet will emit an activate event any time a new component is being instantiated, and a deactivate event when it is being destroyed.

Hence you can use these feature and get your work done.You can see elaborated answer here and a plunker is attached in the same answer

Upvotes: 1

Related Questions