With checkboxes, the Angular form control value is bound to the "checked" state (not the "value" attribute), so it should be either true or false.
Also, you are mixing reactive forms and template-driven forms. You probably should do one or the other.
Template-Driven Form
If you want to use template-driven forms, you can change your template like this:
...
<form name="optOutForm" (ngSubmit)="onSubmit()" #f="ngForm">
<div>
<input type="checkbox" name="privacyOptIn" id="privacyOptIn"
[(ngModel)]="optIn.privacy" required>
<label for="privacyOptIn">Privacy</label>
</div>
<div>
<input type="checkbox" name="securityOptIn" id="securityOptIn"
[(ngModel)]="optIn.security" required>
<label for="securityOptIn">Security</label>
</div>
<div>
<input type="checkbox" name="consentOptIn" id="consentOptIn"
[(ngModel)]="optIn.consent" required>
<label for="consentOptIn">Consent</label>
</div>
<button>Submit Preference</button>
</form>
...
And have your component like this. Notice the model optIn has properties all set to true so the checkboxes are ticked by default.
export class MyComponent {
optIn: {
privacy: boolean;
security: boolean;
consent: boolean;
} = {
privacy: true,
security: true,
consent: true
};
onSubmit() {
...
}
}
See Stackblitz example here.
Reactive Form
If however, you want to go reactive forms, you can change your template like this:
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div>
<input type="checkbox" formControlName="privacyOptIn" id="privacyOptIn">
<label for="privacy">Privacy</label>
</div>
<div>
<input type="checkbox" formControlName="securityOptIn" id="securityOptIn">
<label for="security">Security</label>
</div>
<div>
<input type="checkbox" formControlName="consentOptIn" id="consentOptIn">
<label for="consent">Consent</label>
</div>
<button>Submit Preference</button>
</form>
Then you can set the form in your component like this:
export class MyComponent implements OnInit {
form: FormGroup;
submitted = false;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.form = this.formBuilder.group({
privacyOptIn: [true, Validators.required],
securityOptIn: [true, Validators.required],
consentOptIn: [true, Validators.required]
});
}
// Convenience getter for easy access to form fields
get f() { return this.form.controls; }
onSubmit() {
...
}
}
See Stackblitz example here.
UPDATE
If you want your component to return/emit 'optin' or 'optout' strings, you can simply introduce a new variable in the component during form submission:
export class MyComponent {
@Output() options = new EventEmitter<{
privacy: string;
security: string;
consent: string;
}>();
...
onSubmit() {
const emittedOptions = {
privacy: this.optIn.privacy ? 'optin' : 'optout',
security: this.optIn.security ? 'optin' : 'optout',
consent: this.optIn.consent ? 'optin' : 'optout',
}
this.options.emit(emittedOptions);
}
See it work here