I have https://stackblitz.com/edit/ingecalc?file=src/app/app.component.ts
paramsFormArray: FormArray;
properties: Record<string, number> = { a: 1, b: 2 };
constructor(private fb: FormBuilder) {
this.paramsFormArray = this.fb.group(
this.properties,
);
}
Now I want that for each property
in properties
to have an input
in the HTML.
a = [1 ]
b = [2 ]
c = ...
d = ...
However it does not work. I tried also "array" instead of "group" does not work either...
There is a lot of things going wrong. So Ill give my level best to explain, please ask any doubts if you have any.
Calculator needs to be a service ( basically the same as class, but is accessible through constructor, like how you did, class cannot be accessed through constructor ( through Dependency Injection)
Form Group needs to be initialized and we can subscribe to an observable of formgroup called valueChanges
this will trigger whenever the value gets changed.
In HTML we can wrap the controls inside a form and add the attribute [formGroup]="formGroup"
this will map the created form group to the controls set in HTML.
we do not need ngModel
or keyDown
since we subscribe to the changes!
component details
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { debounceTime, Subscription } from 'rxjs';
import { CalculatorService } from './calculator.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
subscription: Subscription = new Subscription();
debounceTime = 500;
paramsFormGroup: FormGroup;
properties: any = { a: 1, b: 2, c: 0, d: 0 };
constructor(private fb: FormBuilder, private calculator: CalculatorService) {
this.paramsFormGroup = this.fb.group(this.properties);
}
ngOnInit(): void {
this.functionToBeCalled();
this.subscription.add(
this.paramsFormGroup.valueChanges
.pipe(debounceTime(this.debounceTime))
.subscribe(() => {
this.functionToBeCalled();
})
);
}
getControlLabel(type: string) {
console.log(this.paramsFormGroup && this.paramsFormGroup.controls, type);
if (
this.paramsFormGroup &&
this.paramsFormGroup.controls &&
this.paramsFormGroup.controls[type]
) {
return this.paramsFormGroup.controls[type].value;
}
return 0;
}
functionToBeCalled() {
const { a, b } = this.paramsFormGroup.value;
const newProperties = this.calculator.calculate({ a, b });
this.paramsFormGroup.patchValue(newProperties);
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
service details
import { Injectable } from '@angular/core';
import { C } from './calculator/c';
import { D } from './calculator/d';
@Injectable()
export class CalculatorService {
constructor() {}
calculate(properties: Record<string, number>) {
const a = properties['a'];
const b = properties['b'];
const c = C(a, b);
const d = D(a, b);
properties['c'] = c;
properties['d'] = d;
return properties;
}
}