Home > Blockchain >  RXJS debounceTime() with angular firebase getDoc()
RXJS debounceTime() with angular firebase getDoc()

Time:10-04

I'm trying to check the Firestore collections of id by using debounceTime() if IDs exist to avoid a high frequency of reads. But, it seems that the debounceTime() is not working as expected, as it reads almost instantly.

Here is the function calling checking for the id:

checkId(id: string) {
    debounceTime(3000);
    return getDoc(doc(this.firestore, 'users', id))
}

I definitely think I'm using debounce time wrongly here.

CodePudding user response:

debounceTime is an operator, so you'll have to use it in a pipe so that it applies on the data stream that you want to. getDoc returns a Promise so you could convert it to an Observable first and the simply apply the debounceTime operator.

checkId(id: string): Observable<any> {
    //using from to convert Promise to an Obsser
    return from(getDoc(doc(this.firestore, 'users', id))); 
}

randomFunction(): void {
  this.checkId(123)
      .pipe( debounceTime(3000);) //using pipe to apply debounceTime
      .subscribe(response => { console.log(response)  // fetching the response here
      });
}

CodePudding user response:

@HassanMoin's solution is almost right, but there's a huge issue on it : calling the function randomFunction will return a new instance of the observable, creating a new subscription.

Try making a variable for it, for instance :

idControl = new FormControl('');
user$ = this.idControl.valueChanges.pipe(
  debounceTime(3000),
  switchMap(id => this.checkId(id))
);

This way you have a single subscrpition, that automatically gets cancelles when you change the ID.

CodePudding user response:

Not sure if this is the most functional to use with Firebase/Firestore technique.

I've tried using @CCbet suggestion, return as Observable, but it still does not denounce.

So, with @martin suggestion, I look into the rxjs.dev/guide/operators documentation and wrap the function in an rxjs Subject and call it.

private subject: Subject<string> = new Subject();

this.subject.pipe(debounceTime(3000)).subscribe((searchTextValue) => {

   const docRef = doc(this.firestore, `usernames/${searchTextValue}`);
   const data = docData(docRef);
          if (data) {
            this.is_available = true;
          } else {
            this.is_available = false;
          }
    });

// calling next to it
this.subject.next(sanitized_username);

This seems to work. Let me know if there is a caveat.

  • Related