1

I have a header.component.ts that should populate a user name once the user is logged in. I'd like to be able to call a function/method on the header.component class from the mainMenuComponent.

This is in the context of angular2. So when I route to my mainmenu.component it should call the header.component to set the user name.

Here is my layout:

app.component:

@Component({
    selector: 'myapp',
    template:`<header userName="{{userName}}"></header>
                        <router-outlet></router-outlet>`,
    directives: [ROUTER_DIRECTIVES, HeaderComponent]   
})

@RouteConfig([
  {path:'/', name:'Login', component: LoginComponent, useAsDefault: true},
  {path:'/mainmenu', name:'MainMenu', component: MainMenuComponent},])

header.component:

@Component({
    selector: 'header',
    templateUrl: 'header.html'     
})

export class HeaderComponent {
       @Input() userName;

       updateHeaderUserName(userName:string) {
                this.userName = userName;
           }
}

login.component:

onSubmit() {
   this._router.navigate( ['MainMenu', {userName: 'John Doe'}] );
}

mainMenuComponent:

export class MainMenuComponent implements OnInit { 

    constructor(
        private _routeParams:RouteParams){}

        ngOnInit() {
          // CAN I CALL THIS FUNCTION OFF THE HEADER.COMPONENT HERE???
          updateHeaderUserName(this._routeParams.get('userName'));     

        }

}

As you can tell from the code I've done attempted a solution using routing params but I can pass the userName all I want when routing to facilitate route component communication but it's not clear if the HeaderComponent is in memory how I call a public function it has?

2
  • 2
    I think there is no relationship between header & main components else you could have used EventEmitter to call updateHeaderUserName method. Now, as per my knowledge I think you should think of using service more specific shared service among components in Angular2. Commented Feb 11, 2016 at 5:02
  • I actually tried EventEmitter and it didn't work and I was wondering why until I took a look at how <header> and <router-outlet> were not related. I briefly toyed with putting <router-outlet> instead the <header> but you comment just confirms what I suspected about the scoping of the elements and it makes sense! Commented Feb 11, 2016 at 15:29

1 Answer 1

2

As @micronyks said, the shared service seems to be the solution. The important thing not to miss is to share the same instance of the service by components.

You can define this service within providers when bootstrapping your application:

bootstrap(MainComponent, [ SharedService ]);

Then you can inject it into both components, LoginComponent and MainMenuComponent. This way you can share the data without calling an updateHeaderUserName on a component you can't reference...

For more detils about dependency injection and hierarchical injectors, you could have a look at this answer:

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you! I've been racking my brain trying to think of scope between the <header> and the <router-outlet> to explain why EventEmitter would not be working. Been reading to get more in-depth knowledge of routing but a simple service was the answer I couldn't find.
once I have my shared service how will the component that uses it know when the value the service contains has changed? If my MainMenuComponent updates SharedService.userName how will the template for HeaderComponent know ShareService.userName has been updated?
To do that, you can add an EventEmitter property in it. This way, you can implement a updateHeaderUserName method in the service: updateHeaderUserName(username) { this.usernameEmitter.emit(username); }. On this other side, components can subscribe on this emitter to be notified: this.usernameEmitter.subscribe((newValue) => { console.log('username updated'); });
You could have a look at the Mark's great answer regarding such concept: stackoverflow.com/questions/34376854/…
OK! I got as far as using an EventEmitter on my SharedService but I wasn't sure how to catch it/watch it. Need to familiarize myself with the Observable library.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.