0

I want to have a return boolean value based on conditions when I call my API that return an object, but I can't figure out how to do it because I get every time a subscription...

This is my code on component.ts:

    result(){
       return checkPiva()
    }
    checkPiva(){
        return this._mysrvUsers.getUserByPIVA('858585847');
    }


and this is my code on service.ts:

        getUserByPIVA(piva: string){
        const currentResellerCode = localStorage.getItem('resellercode')
        const url = env.apiUrl + "endUser/partitaIva?pi="+piva
        return this.httpClient.get(url).pipe(map(res=>{
            if(res){
                return true;
            }else{
                return false
            }
        }))

    }
4
  • Do you want to return boolean value instead Observable<boolean>? Commented Apr 6, 2022 at 10:56
  • Yes, i want to return a boolean value Commented Apr 6, 2022 at 11:07
  • Closest to what you want may be to use .toPromise() and then use async/await, or otherwise use callbacks. Commented Apr 6, 2022 at 11:36
  • .toPromise() is decrypted ! Commented Apr 6, 2022 at 11:37

5 Answers 5

1

RxJS has a function which will transform an Observable into a Promise firstValueFrom:

import { Injectable } from '@angular/core';
import { firstValueFrom, Observable, of } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class FakeService {
  /* get random true or false boolean mocked */
  getBool(): Observable<boolean> {
    return of(Boolean((Math.random() * 2) | 0));
  }

  getBoolAsPromise(): Promise<boolean> {
    return firstValueFrom(this.getBool());
  }
}

In your consumer:

export class SomeComponentClass {

  constructor(private fs: FakeService) {}
  
  async getBool() {
    const bool = await this.fs.getBoolAsPromise();
    console.log(bool);
  }

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

Comments

1

You should really adopt rxjs and reactive principles if you're to use Angular. It can feel overwhelming at first, but it's for the better.

service:

getFoo() {
   return this.http.get('/foo').pipe(map(res => !!res));
}

component:

getFoo() {
   return this.service.getFoo()
      .subscribe(hasFoo => {
         this.result = hasFoo;
      });
}

html:

<button (click)="getFoo()">clickme</button>
<pre>result={{hasFoo}}</pre> 

Comments

1

The request returns an observable so in order to get the value and use it right away you have to convert it to a promise:

getUserByPIVA(piva: string){
    const currentResellerCode = localStorage.getItem('resellercode');
    const url = env.apiUrl + "endUser/partitaIva?pi="+piva;
    return this.httpClient.get(url).pipe(map(res => !!res));
}

async result(){
   return await checkPiva();
}

async checkPiva(){
  return await this._mysrvUsers.getUserByPIVA('858585847').toPromise();
}

And you have to const res = await result(); wherever you are calling that method.

Comments

1

your getUserByPIVA function is returning Observable<boolean> and you cant return a boolean from it. You can subscribe this observable wherever you want and it's the best way or if you want to achieve Synchronous behaviour using it then you can use async await to achieve this.

In order to use async-await you need to convert Observable into promise.For that you can use RxJS 7+ lastValueFrom or toPromise

async useItLike(){
    let result = await lastValueFrom(this._mysrvUsers.getUserByPIVA('858585847'));
    console.log(result); // will print true/false
  }

Comments

0

Thanks everyone, I solved my problem by doing this:

constructor(private httpClient: HttpClient){
        this.validateAsyncPiva = this.validateAsyncPiva.bind(this);
    }

    validateAsyncPiva(params:any){
        return new Promise<void>((resolve, reject)=>{
            const currentResellerCode = localStorage.getItem('resellerCode')
            const url = env.apiUrl + "endUser/partitaIva?pi="+params.value
            this.httpClient.get(url).subscribe({
                next:(res:any)=>{
                    if(res.length<=0){
                    resolve()
                    }
                    else if(res[0].resellerCode == currentResellerCode) {
                        reject('User is already on your list')
                    }else if(res[0].resellerCode != currentResellerCode){
                        reject('User is taken by another RESELLER')
                    }else{
                        resolve()
                    }
                },
                error: (err:any)=>{
                    console.log(err);
                    reject("Cannot contact validation server");
                }
            });
        });
    }

Comments

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.