Home > database >  How to add a value selected in the dropdown of the reactive form as an optional field in the object
How to add a value selected in the dropdown of the reactive form as an optional field in the object

Time:01-09

I've created an angular reactive form. I can enter the name as a normal input field and type in the second dropdown field and the value for that type. There is a type called credential, after selecting it you can enter the user name & password as input fields. Only the value can be input for the non-credential types (String, Int, Number). The problem is that I currently create a createtial object in the form value and send the value to the backend as follows.

{
    "name": "TestJson",
    "type": "credential",
    "value": "",
    "credential": {
        "username": UserName,
        "password": password
    },
    "secure": false,
    "id": "bjbjsdfjb3334weknn12340nvf9r5df"
}

When it is not a credential type, the credential object sends as null.

{
    "name": "testJson",
    "type": "json",
    "value": "{\"name\":\"John\", \"age\":30, \"car\":null}",
    "credential": {
        "username": null,
        "password": null
    },
    "secure": false,
    "environment_id": "nmvsdmfvndfnkdfnsfldf,fd"
}

But when the value is sent with a string or integer type that is not a credential, an error comes from the backend because the values of the credential object are null. How to improve the form builder object so that the credential object is created when the credential type is sent and the credential object is not created when it is not?

form.html

<form id="add-form"
   [formGroup]="createVariableForm">
   <div >
      <label
         for="add-name">{{name}}</label>
      <input id="add-name"
         type="text"
         name="name"
         formControlName="name"
         [maxlength]="64">
   </div>
   <div >
      <label
         for="add-type">{{argument_type}}</label>
      <select
         id="add-type"
         placeholder="select"
         formControlName="type">
         <option value="string">{{string}}</option>
         <option value="credential">{{credential}}</option>
         <option value="boolean">{{boolean}}</option>
         <option value="number">{{number}}</option>
         <option value="integer">{{integer}}</option>
         <option value="json">Json</option>
      </select>
   </div>
   <div  formGroupName = "credential">
      <div *ngIf="createVariableForm.get('type').value === 'credential'" >
         <label
            for="add-value">Username</label>
         <input id="add-username"
            type="text"
            name="username"
            formControlName="username"
            [maxlength]="64">
      </div>
      <div *ngIf="createVariableForm.get('type').value === 'credential'" >
         <label
            for="add-value">Password</label>
         <input id="add-password"
            type="password"
            name="password"
            formControlName="password"
            [maxlength]="64">
      </div>
   </div>
   <div *ngIf="createVariableForm.get('type').value !== 'credential'" >
      <label
         for="add-value">{{value}}</label>
      <input id="add-value"
         type="text"
         name="value"
         formControlName="value"
         [maxlength]="64">
   </div>
   <div >
      <input
         id="add-secure"
         type="checkbox"
         name="secure"
         formControlName="secure">
      <label
         for="add-secure">{{secure}}</label>
   </div>
   <div >
      <button id="add-can"
         type="button"
         
         (click)="cancel()">{{cancel}}</button>
      <button id="add-save"
      type="button"
      
      [disabled]="isBusy"
      (click)="add()">{{add}}</button>
   </div>
</form>

form.ts

ngOnInit(): void {
        this.createForm();
    }

    private createForm(): void {
        this.createVariableForm = this.formBuilder.group({
            name: [''],
            type: [''],
            value: [''],
            credential: this.formBuilder.group({
                username: [],
                password: [],
            }),
            secure: [false],
            environment_id: [this.UtilService.getEnvironmentId()]
        });
    }

CodePudding user response:

You could subscribe to type FormControl changes to decide whether you need to include credential control to the form or not.

ts

private createForm(): void {
  this.createVariableForm = this.formBuilder.group({
    name: [''],
    type: [''],
    value: [''],
    secure: [false],
    environment_id: [1]
  });

  this.createVariableForm.get('type')?.valueChanges
    .pipe(takeUntil(this.destroyed$)).subscribe(value => {
      if (value === 'credential') {
        this.createVariableForm.addControl('credential', this.formBuilder.group({
          username: [],
          password: [],
        }))
      } else if (this.createVariableForm.get('credential')) {
        this.createVariableForm.removeControl('credential');
      }
    })
}

html

<div *ngIf="createVariableForm.get('credential')"  
     formGroupName = "credential">
  <div  >
    <label for="add-value">Username</label>
    <input id="add-username"
            type="text"
            name="username"
            formControlName="username"
            [maxlength]="64">
  </div>
  <div  >
    <label for="add-value">Password</label>
    <input id="add-password"
            type="password"
            name="password"
            formControlName="password"
            [maxlength]="64">
  </div>
</div>
<div *ngIf="!createVariableForm.get('credential')" >
  <label for="add-value">Value</label>
  <input id="add-value"
          type="text"
          name="value"
          formControlName="value"
          [maxlength]="64">
</div>

Ng-run Example

  • Related