Search code examples
angulartypescriptangular-materialscopeangular-components

Angular: How can I pass a variable in FormBuilder.group()?


Provided a variable to the Validators.max() method, but it's not working. What am I doing wrong?

Here the implementation of the model:

maximums.model.ts

export class Maximums {
   id: number;
   max_hr_1: number; 
   max_hr_2: number;
)

Here the implementation of the service:

maximums.service.ts

export class MaximumsService {

  (...)

  constructor(private http: HttpClient) { }

  listMaxs(): Observable<Maximums> {
    return this.http.get<Maximums>('http://localhost:8081/maximums/list'); 
  }  
}

Here the implementation of the component:

activity-form.component.ts

(...)
export class ActivityFormComponent implements OnInit{

maximums: Maximums;
max_hr_1: number; 
max_hr_2: number; 

constructor(private fb: FormBuilder, private maximumsService: MaximumsService){ }

ngOnInit(): void {

   this.maximums = new Maximums();
   this.getMaxs();

   fg: FormGroup;

   this.fg = this.fb.group({
   hr_1: [null, Validators.max(this.max_hr_1)],
   hr_2: [null, Validators.max(this.max_hr_2)],
   });
}

getMaxs(): void {
    this.maximumsService.listMaxs().subscribe(
      (data) => {
        this.maximums = data;
        this.max_hr_1 = this.maximums.max_hr_1; 
        this.max_hr_2 = this.maximums.max_hr_2;
      },
      (erro) => {
        console.log(erro);
      }
    );
  }


(...)

Here the implementation of the template:

activity-form.component.html

(...)

<form name="form" [formGroup]="fg" #f="ngForm">
   <input matInput min="1" type="number" formControlName="hr_1" />
   <mat-error *ngIf="fg.controls['hr_1'].hasError('max')">Maximum is {{max_hr_1}}</mat-error>

   <input matInput min="1" type="number" formControlName="hr_2" />
   <mat-error *ngIf="fg.controls['hr_2'].hasError('max')">Maximum is {{max_hr_2}}</mat-error>
</form>

(...)

Did not work: Validators.max(this.max_hr_1)

Did not work: Validators.max(this.maximums.max_hr_1)


Solution

  • Move the form creation into the subscribe:

    ngOnInit(): void {
       this.maximums = new Maximums();
       this.getMaxs();
    }
    
    getMaxs(): void {
     this.maximumsService.listMaxs().subscribe(
       (data) => {
         this.maximums = data;
         this.max_hr_1 = this.maximums.max_hr_1; 
         this.max_hr_2 = this.maximums.max_hr_2;
         this.createForm();
       },
       (error) => console.log(error)}
      );
    }
    
    private createForm(): void {
      this.fg = this.fb.group({
         hr_1: [null, Validators.max(this.max_hr_1)],
         hr_2: [null, Validators.max(this.max_hr_2)],
      });
    }
    

    Or just add the validators right after you get the response from the http call like the following:

    getMaxs(): void {
     this.maximumsService.listMaxs().subscribe(
       (data) => {
         this.maximums = data;
         this.max_hr_1 = this.maximums.max_hr_1; 
         this.max_hr_2 = this.maximums.max_hr_2;
         
         this.fg.get('hr_1').addValidators(Validators.max(this.max_hr_1));
         this.fg.get('hr_2').addValidators(Validators.max(this.max_hr_2));
       },
       (error) => console.log(error)}
      );
    }