EDIT: Hmm, I should be more clear. This is an angular2-meteor project. Because meteor is reactive, so maybe has other ways. But @lodewijk-bogaards is an good solution for pure Angular2 project.
I am using Angular 2 (TypeScript).
I try to use ChatService
service to pass value "12345" from App
to ChatDetailsComponent
.
If the boolean showChatDetails
is true, it will show "12345" the first time I click the Show button, which works well.
The problem is, if the boolean showChatDetails
is false, it will show "12345" after the second time I click the Show button. I don't know why it works the second time I click it, which should be first time too.
(Please don't switch to [hidden], because I need *ngIf here.)
// app.ts
import {Component, View} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {ChatService} from './chat.service';
import {ChatDetailsComponent} from './chat-details.component';
@Component({
selector: 'app'
})
@View({
directives: [ChatDetailsComponent],
template: `
<button (click)="showButton()">Show</button>
<chat-details-component *ngIf="showChatDetails"></chat-details-component>
`
})
class App {
// Here if it is true, it works well. If it is false, the problem comes.
showChatDetails:boolean = false;
constructor(private _chatService: ChatService) {}
showButton() {
this._chatService.setChatId("12345");
this.showChatDetails = true;
}
}
bootstrap(App, [ChatService]);
// chat-details.component.ts
import {Component, View} from 'angular2/core';
import {ChatService} from './chat.service';
@Component({
selector: 'chat-details-component'
})
@View({
template: `
<div>ID: {{chatId}}</div>
`
})
export class ChatDetailsComponent {
chatId:string;
constructor(private _chatService: ChatService){}
ngOnInit() {
this._chatService.getChatId().subscribe(id => this.chatId = id);
}
}
// chat.service.ts
import {EventEmitter} from 'angular2/core';
export class ChatService {
chatId: EventEmitter<string> = new EventEmitter();
setChatId(id) {
this.chatId.emit(id);
}
getChatId() {
return this.chatId;
}
}
Looks like a race condition to me. If the ChatDetailsComponent
subscribes to the ChatService
after the chatId
has been emitted it will not receive it. This is very easily possible, since Angular will schedule the creation of the component at the same time as Rx schedules the emit of the event.
I can come up with multiple solutions, but I would suggest that you look into using a ReplaySubject instead of an EventEmitter.