I'm trying to use Signals Input in angular 17 to pass a specific form. In the older approach works fine:
@Component({
selector: 'app-user-data-create-update',
standalone: true,
imports: [ReactiveFormsModule, PanelModule, NgStyle],
templateUrl: './user-data-create-update.component.html',
styleUrl: './user-data-create-update.component.scss',
})
export class UserDataCreateUpdateComponent {
// Injects
private readonly formBuilder: FormBuilder = inject(FormBuilder);
// Inputs
@Input() form: Signal<FormGroup<any>>; //works fine
fontSize = input<string>('0.8rem'); //works fine
constructor() {
this.form = signal(
this.formBuilder.group({
createdDateTime: [''],
creatorXID: [''],
creatorPersonXID: [''],
creatorPersonEmail: [''],
updatedDateTime: [''],
updaterXID: [''],
updaterPersonXID: [''],
updaterPersonEmail: [''],
})
);
}
}
Calling component:
<app-user-data-create-update [form]="formGroupProgram"/>
However, I've already tried a lot of things to works with "new" Angular signals with FormGroup and didn't works.
Any idea?
Please initialize the default value inside the function input
.
We can use the input
signal to behave the same as @Input
and receive a new value from the parent, or use the value initialized inside the input
signal initialization.
@Component({
selector: 'app-user-data-create-update',
standalone: true,
imports: [ReactiveFormsModule, PanelModule, NgStyle],
templateUrl: './user-data-create-update.component.html',
styleUrl: './user-data-create-update.component.scss',
})
export class UserDataCreateUpdateComponent {
// Injects
private readonly formBuilder: FormBuilder = inject(FormBuilder);
// Inputs
readonly form: InputSignal<FormGroup<any>> = input(this.getForm()); //works fine
readonly fontSize = input<string>('0.8rem'); //works fine
getForm() {
return this.formBuilder.group({
createdDateTime: [''],
creatorXID: [''],
creatorPersonXID: [''],
creatorPersonEmail: [''],
updatedDateTime: [''],
updaterXID: [''],
updaterPersonXID: [''],
updaterPersonEmail: [''],
});
}
}
If you want the form
state to change in the future, meaning you will override the value with something else locally in your component, then you require something called local state (linkedSignal - will take a value from the signals inside and can also be modified by the user unlike input
signal).
Here we initialize the input
with a different name, but since the different name will affect data binding, we use alias
to set the data binding name as form
@Component({
selector: 'app-user-data-create-update',
standalone: true,
imports: [ReactiveFormsModule, PanelModule, NgStyle],
templateUrl: './user-data-create-update.component.html',
styleUrl: './user-data-create-update.component.scss',
})
export class UserDataCreateUpdateComponent {
// Injects
private readonly formBuilder: FormBuilder = inject(FormBuilder);
// Inputs
readonly formInput: InputSignal<FormGroup<any>> = input(this.getForm(), { alias: 'form' }); //works fine
readonly form: WritableSignal<FormGroup<any>> = linkedSignal(() => this.formInput());
readonly fontSize = input<string>('0.8rem'); //works fine
getForm() {
return this.formBuilder.group({
createdDateTime: [''],
creatorXID: [''],
creatorPersonXID: [''],
creatorPersonEmail: [''],
updatedDateTime: [''],
updaterXID: [''],
updaterPersonXID: [''],
updaterPersonEmail: [''],
});
}
ngAfterViewInit() {
this.form.set( // <- you can change the form state locally if needed
this.formBuilder.group({
createdDateTime: [''],
creatorXID: [''],
})
);
}
}