Search code examples
angularrxjsobservableangular-promise

What is the replacement for $q.when, $q.defer & defer.promise in Angular 6 using Observable


I'm upgrading from Angularjs to Angular 6,In AngularJS they are using Promises and some $q functions, I couldn't find the replacement for some functions. I'm looking for a $q.when, $q.defer, Defer.resolve() and Defer.promise replacement. How to achieve this using Observable?

common.$q.when(checkDuplicate()).then(function (dupSc) {
 if(dupsc.length !== 0){
  some functions...
    }}

function checkDuplicate() {
        var defer = common.$q.defer();
        var url = "XYZ"
        dataService.getData(url).then(function (response) {
            defer.resolve(response.value);
        });
        return defer.promise;
    }

now I want to convert all this functions to Angular 6 using Observable could anyone suggest the best way to replace this in Angular 6 with the example.


Solution

  • As far as I know, there isn't a one to one comparison. $q is essentially an implementation of Promise, and since Angular switched to using RxJs, there was not a one to one mapping. However, whatever you can do with $q is possible in RxJs in a slightly different manner.

    Since it depends on your design requirements how you want to implement your observables, I won't be able to give examples of all cases, but I recently had to transform my own Angular1 project (using $q.defer()) to Angular7 (now using RxJs observables), and here is one example.

    In angular1, the search functionality was: as user types, call backend to get search data, but cancel that request as soon as user types more, and return the most recent data i.e. just like in google. I was using defer() for that.

    In angular2, the same functionality can be achieved using switchMap. switchMap will discard any previous events generated for which results are not yet available with the new event and wait for the new event's results. This is same as resolving the defer() promise prematurely. Below is the code for my angular2 search functionality.

    fromEvent(this.searchTextInput.nativeElement, 'keyup')
      .pipe(
        map((event: KeyboardEvent) => {
          return event.target
        }),
        debounceTime(1000),
        switchMap((searchInput: HTMLInputElement) => {
          this.searchInProgress = true
          this.searchText = searchInput.value
    
          if (this.searchText.length > 0) {
            return this.pluginService.searchPlugins(searchInput.value)
          } else {
            return EMPTY
          }
        })
      )
      .subscribe({
        next: (plugins: Plugin[]) => {
          this.searchInProgress = false
          this.searchResults = plugins
        },
        error: (error: HttpErrorResponse) => {
          this.searchInProgress = false
          this.errorChange.emit(error)
        }
      })