简体   繁体   中英

How to wait for subscribe to finish with pipe and map

In my backend - express.js I am successfully returning a boolean value which tells me if a user exists or not.

Problem is in my frontend - angular(newest version), when I receive that value, I need to use that value right after asynchronous execution.

So I decided to use RxJS pipe + map

I get this:

Argument of type 'Observable<unknown>' is not assignable to parameter of type 'OperatorFunction<boolean, unknown>'.
  Type 'Observable<unknown>' provides no match for the signature '(source: Observable<boolean>): Observable<unknown>'.ts(2345)
The 'this' context of type 'void' is not assignable to method's 'this' of type 'Observable<unknown>'.

ApiService.ts

checkIfUserExists(email: string): Observable<boolean> {
    return this.http.get<boolean>(`${this.COINS_URL}/login/check/${email}`);
  }

register.component.ts

let value = null
        this.apiService.checkIfUserExists(this.user.email)
  .pipe(
    map(data => console.log(data))
  )
    console.log(value) -- returns [object Object]

How do I resolve this issue and use pipe + map successfully?

Edit for comments:

checkIfUserExists() {
    this.user = this.userRegistrationForm.value
    return this.apiService.checkIfUserExists(this.user.email)
      .pipe(
        map(data => data))
      .subscribe(e => e.userExists)
  }

When trying to use - I get [object Object]

userExists = this.checkIfUserExists()
    console.log('userExists: ' + userExists)

Edit 2: Final solution, thanks for all the help Problem was solved using callbacks Big thanks to this post: How do I return the response from an asynchronous call?

Code:

checkIfUserExists(callback) {
    this.user = this.userRegistrationForm.value
    console.log("2. callback here is the function passed as argument above...")
    this.apiService.checkIfUserExists(this.user.email)
      .pipe(
        map(data => data))
      .subscribe(e => {
        console.log("3. start async operation...")
        console.log("4. finished async operation, calling the callback, passing the result...")
        callback(e.userExists)
      })
  }

onSubmit() {
    let userExists = null
    console.log("1. function called...")
    this.checkIfUserExists((result: boolean) => {
      // 5. Received the result from the async function,
      //    now do whatever you want with it:
      console.log("5. result is: ", result);
      userExists = result
      this.userExistsValidator(userExists)
  });
  }

You need to return from.pipe(map), like below. This will cause function to wait for service to get the response and then return the value. So doing this will not return null value or return from function before service has get any response.

let value = null
        return this.apiService.checkIfUserExists(this.user.email)
  .pipe(
    map(data =>{
    console.log(data);    
    return data; 
    })
  );

Take a look at the signature of map from the documentation. You will need to return an observable. Signature:

map(project: Function, thisArg: any): Observable

Now make the following change:

checkIfUserExists() { 
   return this.apiService.checkIfUserExists(this.user.email)
    .pipe(
      map(data => data)  // needed only if you need projection
      })
    );
}

Points to note:

  1. Omit the {} and return when there is just one statement within the map operator.
  2. In this case, I don't think you need the map operator unless you are trying to project certain properties from the observable.
  3. Unless you subscribe to an observable, it will not emit the values from it.

Invoke it using: (since it is asynchronous)

this.checkIfUserExists().subscribe(e => userExists = e);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM