Return result of an observable with combineLatest and Rxjs

Viewed 419

I wish to get the result of an observable which substract the default value each time the value change

Each time the value changes it substract the default value by the new value entered into the input field

For example default value is 5.

I enter 4 into the input field

The result is 5-4 = 1 so I wish to display 1 into the input field "Surface ha"

I clear the field then I enter 3 The result is 5-3 = 2 so I wish to display 2 into the input field "Surface ha"

And so so ....

If I do a console.log I can clearly see the result of the observable but, I wish to display the result of the observable into the same input field

I only get this kind of error result in my dev console:

NaN

The view:

   <form [formGroup]="credentialsForm" *ngIf="credentialsForm">
    <mat-form-field class="example-full-width">
        <mat-label>Surface Ha</mat-label>
        <input matInput type="number" [value]="surface" placeholder="Libellé" formControlName='surface'>
    </mat-form-field>

    <ion-input  class="form-control" placeholder="Valeur" 
                formControlName="0">
            </ion-input>
   </form>

Inside the component:

    this.surface = 5;

    const observedValues = ['0']
    .map(key => this.credentialsForm.controls[key].valueChanges.map(value => +value).startWith(0))

    const resSurface = combineLatest(observedValues)
    .pipe(map(([value0]) => { return this.surface - value0 }));
    

    const res = resSurface.subscribe(val => { return val });

   // These line below should display the "res" value
    this.surface = res;
2 Answers

You need to assign the values emitted by the Observable to this.surface, rather than the subscription itself:

resSurface.subscribe(val => this.surface = val);

Alternatively, you can get rid of the subscribe call and use the Angular async pipe to bind directly to the Observable:

this.resSurface = combineLatest(observedValues)
                    .pipe(map(([value0, value1, value2]) => { return this.surface - (value0 + value1 + value2) }));

And then in your template:

<input matInput type="number" [value]="resSurface | async" placeholder="Libellé" formControlName='surface'>

I forgot to start with a different default value !

            let defaultValueSurface = 5;

            const observedValues = ['0']
            .map(key => this.credentialsForm.controls[key].valueChanges.map(value => +value).startWith(0))

            const resSurface = combineLatest(observedValues)
            .pipe(map(([value0]) => { return defaultValueSurface - value0 }));
            
        
            const res = resSurface.subscribe(val => { return val });

         
            this.surface = res;
Related