David Lerma Developer
David Lerma Developer

Reputation: 143

How to concatenate values using Reactive Forms?

I want to concatenate 2 values into 1 label using Reactive Forms. In this case i'm not using ngModel binding.

 <label 
                     id="identificationCode"
                     name="identificationCode"
                     formControlName="lblIdCode">______</label>

<input type="text" 
                        id="reference"
                        name="reference"
                        formControlName="txtReference"
                        maxlength="250"
                        (change)="handleIdCode($event)">

<input type="text" 
                        id="publicacion"
                        name="publicacion"
                        formControlName="txtPublicacion"
                        maxlength="250"
                        (change)="handleIdCode($event)">

I want to concatenate those 2 input text when user is writing and automatically reflect the value into the label. Is there any way like we do it with model binding without change event??

Upvotes: 3

Views: 5744

Answers (5)

user2216584
user2216584

Reputation: 5612

Although given answers work fine. There could be another declarative approach which will take advantage of valueChanges observables of the input text. We can combine the input texts' valuechanges observables and map to the desired output i.e. concatenate the Reference + Publicacion like this:

Component.ts:

export class FormreactiveComponent implements OnInit {
  lblIdCode$: Observable<string>;

  form = new FormGroup({
    txtReference: new FormControl(''),
    txtPublicacion: new FormControl('')    
   });

  constructor() { }

  ngOnInit() {

    const refCtrl = this.form.get('txtReference');
    const pubCtrl = this.form.get('txtPublicacion');

    this.lblIdCode$ = combineLatest(refCtrl.valueChanges.pipe(startWith(refCtrl.value)), 
                                   pubCtrl.valueChanges.pipe(startWith(pubCtrl.value)))
                      .pipe(map(([firstName, lastName]) => {
                        return `${firstName} ${lastName}`;
                      }));
  }    
}

Template:

<form name="form" [formGroup]="form">
      <div class="form-group">
        <label for="txtReference">Reference</label>
        <input type="text"  class="form-control" formControlName="txtReference"/>            
      </div>
      <div class="form-group">
        <label for="txtPublicacion">Publicacion</label>
        <input type="text" class="form-control" formControlName="txtPublicacion"/>            
      </div> 
      <div class="form-group">
        <label for="lblIdCode">{{lblIdCode$ | async}}</label>             
      </div>          
</form>

Working example

Upvotes: 1

Steve
Steve

Reputation: 2343

One approach is that you can use reference variables to refer to controls within the template. Like so

<label 
 id="identificationCode"
 name="identificationCode">{{reference.value + " - " + publicacion.value}}</label>

<input type="text" 
 id="reference"
 name="reference"
 formControlName="txtReference"
 maxlength="250"
 #reference>

<input type="text" 
 id="publicacion"
 name="publicacion"
 formControlName="txtPublicacion"
 maxlength="250"
 #publicacion>

The important parts are the #reference and #publicacion on each of the inputs. This links the controls to the variables.

You can then use these variables within an Angular interpolation block like {{reference.value + " - " + publicacion.value}}. You can combine the values however you want inside this block.

Upvotes: 0

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24474

you can create a get property base of these values like in

componenpe ts

get referencePublicacionValues() : string {
 return `${this.form.get(txtReference).value} ${this.form.get('txtPublicacion').value}`
}

template

<label 
     id="identificationCode"
     name="identificationCode">
     {{referencePublicacionValues}}
</label>

now you have the value in reference Publicacion Values property any change the value will reflect to the ui

you can't use formControlName directive on labels if you want to set the formcontrol lblIdCode you can use form valueChanges

this.form.valueChanges.subscribe( () => {
 this.form.get('lblIdCode').setValue(this.referencePublicacionValues,{emitEvent: false})
})

demo 🔥🔥

Upvotes: 0

Maihan Nijat
Maihan Nijat

Reputation: 9355

Use label to display the information. The label is not meant to bind with Reactive Form. If you need concatenate values to pass to API or for any use then try on TS. User cannot change the value of Label so there is no point to bind it, but just display the concatenated value.

Remove formControlName="lblIdCode" from your label and add for attribute.

<label>{{form.get('txtReference').value}} - {{form.get('txtPublicacion').value}}</label>

And concatenate on TS:

const lblIdCode = this.form.get('txtReference').value + this.form.get('txtPublicacion').value

The definition of label:

The HTML element represents a caption for an item in a user interface.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label

Upvotes: 2

Rydyell
Rydyell

Reputation: 31

Try using the form values, just like you'd use in the .ts file.

<label 
     id="identificationCode"
     name="identificationCode"
     formControlName="lblIdCode">
     {{form.value.reference + ' ' + form.value.publicacion}}
</label>

Upvotes: 0

Related Questions