Search code examples
angularprimengangular-forms

How to pass selected checkbox values into childcomponent with PrimeNg without using NgModel? Angular


I have a basic app where I have a form and I am wanting to pass in selected checkbox values down to the child component, so that the checkboxes which are selected in the p-multiSelect on the parent are the only items that appear in the p-dropdown in the child.

Using [(ngModel)] this works for the most part except when I am patching values into the p-multiSelect options with data from an API. Also, this results in the following error:

It looks like you're using ngModel on the same form field as formControlName. 
Support for using the ngModel input property and
ngModelChange event with reactive form directives has been deprecated
in Angular v6 and will be removed in Angular v7

For more information on this, see our API docs here: https://angular.io/api/forms/FormControlName#use-with-ngmodel

I haven't been able to figure out a good way to get this to work since I am passing down a selected value which seems like it does need to come from the [(ngModel)]. Is there a different way to pass down the select items from the p-multiSelect into the child component without using the ngModel?

As you will be able to see in the code, this IS working. The value is being passed down. However, if I use patchValue() on the form and bring this multiSelect option in from somewhere else, it does not work with the NgModel. I am also getting the error above because I am using ngModel on a FormControlName

Here is a stackblitz and code is below. I have simplified it tremendously and removed the form from the child component so it is just getting the value.

AppComponent.html

<div style="padding: 10px; border: solid black 1px">
    <form [formGroup]="form">
        <span>Parent Component. Multi-select, where selected items are input into child comp dropdown</span>
        <br>
        <p-multiSelect 
      [options]="statementOptions" 
      formControlName="statements" 
      [(ngModel)]="selectedStatements">
        </p-multiSelect>

        <div style="margin-top: 10px; padding: 5px; border: solid black 1px;">
            <span>Child Component, I want to receive selected items ,but am unaway how to without using ngModel</span>
            <app-select-statements [statements]='selectedStatements'>
            </app-select-statements>
        </div>
    </form>
</div>

AppComponent.Ts

export class AppComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      statements: ''
    })
  }
  statementOptions = [
    { label: 'Item1', value: 'item1' },
    { label: 'item2', value: 'item2' },
    { label: 'Item3', value: 'item3' },
    { label: 'Item4', value: 'item4' },
    { label: 'Item5', value: 'item5' },
  ];
}

SelectStatementComponent

@Component({
  selector: 'app-select-statements',
  template: `
    <div> 
      <p-dropdown 
        placeholder="Choose"
        [options]="statements"
        ></p-dropdown>
    </div>
  `,
})
export class StatementComponent implements OnChanges {
  @Input() statements;

  //this maps the values in order to get back the 
  //label and value as required by the PrimeNg dropdown
  ngOnChanges() {
    if(this.statements) {
      this.statements = this.statements.map((s) => ({
        label: s,
        value: s
      }))
    }
  }
}

Solution

  • Maybe just use the form value?

    <app-select-statements [statements]="form.get('statements').value">