angular - Retornar resultado de um observable com combineLatest e Rxjs


Desejo obter o resultado de um observável que subtrai o valor padrão cada vez que o valor muda

Cada vez que o valor muda, ele subtrai o valor padrão pelo novo valor introduzido no campo de entrada

Por exemplo, o valor predefinido é 5.

Eu insiro 4 no campo de entrada

O resultado é 5-4=1, por isso desejo mostrar 1 no campo de entrada "Superfície ha"

Eu limpo o campo, depois insiro 3. O resultado é 5-3=2, então desejo mostrar 2 no campo de entrada "Superfície ha"

E assim assim ....

Se eu fizer um console.log, consigo ver claramente o resultado do observable, mas, eu gostaria de mostrar o resultado do observable no mesmo campo de input

Só obtenho este tipo de resultado de erro no meu consolo de desenvolvimento:

Não é um número

A vista:

   <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>

Dentro do componente:

    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;

Resposta #1

Precisa de atribuir os valores emitidos pelo Observable a this.surface, em vez da própria subscrição:

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

Alternativamente, pode livrar-se da chamada subscribe e usar o pipe async do Angular para ligar diretamente ao Observable:

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

E depois no seu modelo:

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

Resposta #2

Esqueci-me de começar com um valor predefinido diferente!

            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;