1

I have a form which displays some inputs with their value that I get from my JSON database, and I want to have the possibility the update them if needed.

Here's the HTML:

<!-- Start form to update resim request -->
<form class="formUpdateRequest" [formGroup]="updateRequestForm" (ngSubmit)="handleSubmitUpdateRequest()">

    <span class="spanTextSil"><b> | MR : </b></span>
    <input formControlName="numMergeRequest"  class="inputForm" type="number" value="{{ Request?.numMergeRequest }}" />

</form>

and how I recover it:

@Component({
  selector: 'app-request-details',
  imports: [ReactiveFormsModule],
  templateUrl: './request-details.html',
  styleUrl: './request-details.css'
})

export class RequestDetails {

  route: ActivatedRoute = inject(ActivatedRoute);
  RequestService = inject(RequestService);
  Request: RequestInfo | undefined ;

  constructor() {

  
    this.RequestService.getRequestById(this.route.snapshot.params['id'])
      .then((Request) => {
        this.Request = Request;
    });


  }

and the service:

async getRequestById(id: number): Promise<RequestInfo | undefined> {

    const data = await fetch(`${this.urlRequest}?id=${id}`);
    const RequestJson = await data.json();

    return RequestJson[0] ?? {};
  }

But, with Angular, the FormGroup initialize the default value and the input is empty instead of display its value. and the field is just empty.

updateRequestForm = new FormGroup ({  

    numMergeRequest: new FormControl('', Validators.min(1)),

  });

I know it's possible to set a default value, but I don't succeed to put my Request element, it tell that it's not possible to put a undefined var.

I succeed to recover my object, but I don't know how to access to specific element of it.

this.RequestService.getRequestByIdDefined(this.route.snapshot.params['id'])
      .then((RequestTest) => {
        this.RequestTest = RequestTest;
        console.log(this.RequestTest)
    });

How to put correctly the default value from the database?

1 Answer 1

1

Angular initializes the FormGroup before your HTTP (or fetch) call returns the data.
So when the form is created, this.Request is still undefined, meaning the form control starts empty.

Correct Solution: patch values after the data is loaded


constructor() {
  this.RequestService.getRequestById(this.route.snapshot.params['id'])
    .then((Request) => {
      this.Request = Request;
      this.updateRequestForm.patchValue({
        numMergeRequest: this.Request?.numMergeRequest
      });
    });
}

Form Initialization (no default yet)

updateRequestForm = new FormGroup({
  numMergeRequest: new FormControl('', Validators.min(1))
});

Remove value="{{ ... }}" in the template

Reactive forms should not use [value] or value="{{ }}". The form already controls the input value.

<input formControlName="numMergeRequest" class="inputForm" type="number" />

Try this way

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your help, it almost work perfectly ! It works for input type = "text" but if I want to initialize an input type number, I have to put it like this : "numMergeRequest: new FormControl(),". Do you know how I can replace the '?' in that => numMergeRequest: new FormControl(?, Validators.min(1)), ?
You always can "convert" to number (see the "+" -convert to number- and the "||" -if not defined the property return 0-this.updateRequestForm.patchValue({ numMergeRequest:+this.Request?.numMergeRequest||0 });. NOTE: when use reactiveForms NEVER use value, the input get the value of the formControl.
Thanks again for your help, it's completly good now

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.