1

I am trying to create a custom reusable select-input component in Angular Reactive Forms. The component should be used in parent component form (register form in my case). But i am not able to detect changes on child component (select-input component) pass them to the parent component. Here is what i have tried

select-input.component.ts

@Component({
  selector: 'select-input',
  templateUrl: './select-input.component.html',
  styleUrls: ['./select-input.component.css']
})
export class SelectInputComponent implements ControlValueAccessor 
{
  @Input() label: string;
  @Input() name: string;
  @Input() options: {value: string}[];
  
  constructor() { }

  writeValue(obj: any): void
  {
    
  }
  registerOnChange(fn: any): void
  {
    
  }
  registerOnTouched(fn: any): void
  {
    
  }
}  

select-input.component.html

<div>
    <label for={{name}} style="margin-right: 2px;">{{label}}:</label>
    <select name={{name}}>
        <option *ngFor="let option of options" [value]="option.value">
            {{option.value}}
        </option>
    </select>
</div>

register.component.ts

export class RegisterComponent implements OnInit 
{
  countries: {name: string}[] = [
    {value: 'Canada'},
    {value: 'USA'},
    {value: 'UK'},
    {value: 'Japan'},
  ]
  registerForm: FormGroup;

  constructor (private fb: FormBuilder) {}

  ngOnInit(): void 
  {
    this.initializeForm();
  }
  
  initializeForm()
  {
    this.registerForm = this.fb.group({
      username: ['', Validators.required],
      country: [this.countries]
    })
    
  }
}

register.component.html

<select-input [formControl]='registerForm.controls["country"]' ngDefaultControl
        [label]='"Country"' [name]='"countries"' [options]="countries">
</select-input>

How can detect changes on child component(select-input) and propagate them on parent component(register-form) ?

Kenzo
  • 1,767
  • 8
  • 30
  • 53
  • How to propagate them - You call the `onChanged` copy of `fn` callback you copied when `registerOnChange` runs. See [this](https://stackoverflow.com/a/57280011/4711754) – Andrew Allen Sep 27 '22 at 13:54
  • How can you eleborate on that ? Thanks – Kenzo Sep 27 '22 at 14:19
  • `registerOnChange(fn: any) { this.onChanged = fn }` i.e. register the on change function and call `this.onChanged(someValue)` to let the parent know. You'd need to call this in the child whenever the select changes. And use ` – Andrew Allen Sep 27 '22 at 14:23
  • where exactly to call ``this.onChanged(someValue)`` in child component ? – Kenzo Sep 27 '22 at 14:31
  • e.g. https://stackoverflow.com/a/5024082/4711754 – Andrew Allen Sep 27 '22 at 14:50
  • Can't you just use `@Output() EventEmitter` ? Or does the `registerForm` not emit events? – Pieterjan Sep 27 '22 at 16:41

0 Answers0