I am working on an Angular2 application and one of the @Components has a button that when clicked will send a post request to my server which will either respond with an Ok(string) or a BadRequest(string).
I am having trouble updating an @Input field of one of my @Components after getting the answer from the server.
Below are simplified version of some of my classes.
My Component class
@Component({
moduleId: module.id,
selector: 'model-comp',
templateUrl: './model.component.html',
styleUrls: ['./model.component.css']
})
export class MyComponent{
@Input() model: Model;
@Output() emitter: EventEmitter<Model> = new EventEmitter<Model>();
public constructor(private service: MyService){}
public toggle(): void {
this.service.send(model.id, model.name){
.subscribe(
result => this.onSuccess(result)),
error => this.onError(error),
() => this.onComplete());
}
public onSuccess(result: string): void {
if(result.inculdes("Some Text")) this.model.flag = true;
else this.model.flag = false;
this.emitter.emit(this.model);
}
public onError(error: any): void {
//notification using bootstrap-notify
}
public onComplete(): void {
//currently empty
}
}
My Service class
export class MyService{
public send(id: string, name: string){
return <Observable<string>>this.http
.post('url', new Dto(id, name))
.map(result => this.getData<string>(result))
.catch(this.catchBadResponse);
}
private getData<E>(result: Response): E {
//checking if result.status is ok
var body = result.json ? res.json(): null;
return <E>(body || {});
}
private catchBadRespomse: (error: any) => Observable<any> = (error: any) => {
var response = <Response>error;
var json = response.json();
var msg = json.Message;
var errormsg = json?
(json.error ? json.error: JSON.stringify(msg?msg:json)) :
(response.statusText || 'Error?');
return Obserable.of(errormsg);
}
}
Template of MyComponent
<button (click)="toggle()"
[ngClass]="{'class1': true, 'class2': model.flag}">Text</button>
Template of Parent Component
<div *ngFor="let model of getList()">
<model-comp [model]="model" (emitter)="onEmit($event)"></model-comp>
</div>
The onEmit Function
onEmit(evt: any): void{
if(evt instanceof Model){
var evtModel = evt as Model;
this.list.find(search => search.id == evtModel.id)
.isFav = evtModel.isFav;
}
}
The problem is that even though I post my data and receive the response, The property flag of my model does not change.
I think that the click event reloads the component thus removing the observers of the EventEmitter.
So is there any way to cancel the reload, not lose the observers of the EventEmitter or any other way to update the root object or the element class?
@Input() model:Model;and@Output() modelChange:EventEmitter<Model> = ...then you can use "two-way" binding like[(model)]="someProp"model.flagis not changed - because theclass2is not added?<button (click)="model.flag = !model.flag">click me</button>and check if this results in the expected behavior?