EventEmitter from Subcomponent not working

466 views Asked by At

I want to have a two-way-binding from a parent-component to a sub-component. This already works well in one of my components which looks as follows (I emitted some css-classes and other not relevant parts):

parent habit-show.component.html:

{{habit.label}}
<app-habit-edit [(habit)]="habit" ></app-habit-edit>

subcomponent habit-edit.component.html:

<input id="habitName" name="label" [(ngModel)]="habit.label" required/>

subcomponent habit-edit.component.ts:

@Input()
private habit: Habit ;

@Output()
habitChange = new EventEmitter<Habit>();

This works as expected: I can see the habit.label in the parent-component and when I change the value in the input it automatically changes too. Now this is the part of the component that isn't working:

parent habit-edit.component.html:

 {{habit.goalActive}}
 <app-checkbox [(mappedModel)]="habit.goalActive" ></app-checkbox>

subcomponent checkbox.component.html:

 {{mappedModel}}
 <input name="checkbox-input" [(ngModel)]="mappedModel" type="checkbox">

subcomponent checkbox.component.ts:

 @Input()
 private mappedModel: boolean;

 @Output()
 mappedModelChange = new EventEmitter<boolean>();

Now in this case, the value in the parent-component doesn't update and I have no idea why, since I did basically the same. The value in the child-component does update correctly.

One thing worth noting might be, that the child component from the first (working) example is the parent in the second example -> that shouldn't be a problem though, should it?

Also the updating of the parent container works when I add a button whenever I press that button (it still doesn't update from the checkbox value though):

parent habit-edit.component.html:

 {{habit.goalActive}}
 <app-checkbox [(mappedModel)]="habit.goalActive" ></app-checkbox>

subcomponent checkbox.component.html:

 {{mappedModel}}
 <input name="checkbox-input" [(ngModel)]="mappedModel" type="checkbox">
 <button (click)="test()">Test</button>

subcomponent checkbox.component.ts:

 @Input()
 private mappedModel: boolean;

 @Output()
 mappedModelChange = new EventEmitter<boolean>();

 test(){
    this.mappedModel = !this.mappedModel;
   this.mappedModelChange.emit(this.mappedModel);
 }

And if I add the test-function to the input itself, nothing at all happens, whenever I press it (not even the mappedModel in the child component updates then)

<label (click)="test()">{{mappedModel}}
   <input name="checkbox-input" [(ngModel)]="mappedModel" type="checkbox">

The problem seems to be that I can't properly bind habit.goalActive with the eventemitter from the subcomponent (maybe because it is the property of an object an not the whole object?) I'm still confused though, since this is no problem with [(ngModel)] on inputs

2

There are 2 answers

6
Thivanka Saranatha On BEST ANSWER

in your input in child component add change event and call test fuction and remove the ngModel

<input name="checkbox-input"  [ngModel]="mappedModel" (change)="test()" type="checkbox">
1
Cyril On

I think you are not using your event. It work in the first example because you use the same object in parent and child.

Can you try this :

<app-checkbox [(mappedModel)]="habit.goalActive = $event" ></app-checkbox>