Matthew Brown
Matthew Brown

Reputation: 5136

Angular 2 Beta0 - Cant get Event Emitters to work

This is driving me nuts. I have an Angular2 application that I am trying to finish the login feature on. All I'm trying to do at this point is update the Navbar component template with the logged in users username when they login successfully. I am attempting to use EventEmitter to do this but the subscribe part never fires.

Everything builds/compiles OK - no errors. And the navbar does update, but only after a hard refresh. I'm trying to update it without the user needing to refresh

LoginService

@Injectable()
export class LoginService {

   constructor(..., private userService: UserService) {
      //
   }

   postLogin(f: ControlGroup) {
      // Submits Login Form Etc.
      // Calls UserService to 'Set User'
      this.userService.setUser(user);
   }
}

UserService

@Injectable()
export class UserService {

    // My EventEmitter Here (I've tried without @Ouput() too)
    @Output() userChange: EventEmitter<any> = new EventEmitter();

    constructor() {
        //
    }

    setUser(user: any) {
        // Do some stuff with user
        this.localStorage.setObject('user', user);

        // Emit User Change Event (This logs to console OK)
        console.log('Emitting User');
        this.userChange.emit({ user: user });
    }
}

NavBar Component This is where I want to update User on Event Fire.

@Component({
    selector: "navbar",
    directives: [<any>RouterLink, <any>NgIf],
    providers: [UserService],
    template: require('./index.html'),
    //... I've tried 'events:[], inputs:[], properties[] - No success
})

export class Navbar {

    /**
     * @type {}
     */
    user: any = {};


    constructor(private userService: UserService) {
        let self = this;

        // I expect this to log to console, but never does
        userService.userChange.subscribe((data) => {
            console.log('Caught Event');
            self.user = data.user;
        });
    }
}

Navbar Template

<!-- User Authed Menu -->
<li *ngIf="loggedIn" class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" (click)="userDrop = !userDrop" href="#" role="button">
        {{ user.username }}
    </a>
    <div class="dropdown-menu" [hidden]="!userDrop">
        <a class="dropdown-item" [routerLink]="['./Login']" (click)="userDrop = !userDrop">Logout</a>
    </div>
</li>

NavbarComponent is under an AppComponent as well, not sure if that matters.

I have also tried just updating a user object on the shared UserService and referencing it from nav component, but that wasn't working either. I have a fairly strong angular 1 background and I am still lost on why this isn't working. Any help would be really appreciated.

Upvotes: 0

Views: 130

Answers (1)

Mark Rajcok
Mark Rajcok

Reputation: 364727

As discussed in the OP comments, because the NavBar component has providers: [UserService], it was injecting its own instance of the service.

Removing providers: [UserService] from the NavBar component and adding it further up the component tree allows multiple components to share one instance.

For something like a UserService, where you likely only want one instance, you can put providers: [UserService] in the root component, or specify the service in the call to bootstrap(AppComponent, [UserService]).

Upvotes: 3

Related Questions