Return an empty Observable

JavascriptTypescriptRxjsObservable

Javascript Problem Overview


The function more() is supposed to return an Observable from a get request

export class Collection {
  public more = (): Observable<Response> => {
    if (this.hasMore()) {
      return this.fetch();
    } else {
      // return empty observable
    }
  };

  private fetch = (): Observable<Response> => {
    return this.http.get("some-url").map((res) => {
      return res.json();
    });
  };
}

In this case I can only do a request if hasMore() is true, else I get an error on subscribe() function subscribe is not defined, how can I return an empty Observable?

this.collection.more().subscribe(
  (res) => {
    console.log(res);
  }, (err) => {
    console.log(err);
  }
);

Javascript Solutions


Solution 1 - Javascript

With the new syntax of RxJS 5.5+, this becomes as the following:

// RxJS 6
import { EMPTY, empty, of } from "rxjs";

// rxjs 5.5+ (<6)
import { empty } from "rxjs/observable/empty";
import { of } from "rxjs/observable/of";

empty(); // deprecated use EMPTY
EMPTY;
of({});

Just one thing to keep in mind, EMPTY completes the observable, so it won't trigger next in your stream, but only completes. So if you have, for instance, tap, they might not get trigger as you wish (see an example below).

Whereas of({}) creates an Observable and emits next with a value of {} and then it completes the Observable.

E.g.:

EMPTY.pipe(
    tap(() => console.warn("i will not reach here, as i am complete"))
).subscribe();

of({}).pipe(
    tap(() => console.warn("i will reach here and complete"))
).subscribe();

Solution 2 - Javascript

For typescript you can specify generic param of your empty observable like this:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();

Solution 3 - Javascript

RxJS6 (without compatibility package installed)

There's now an EMPTY constant and an empty function.

  import { Observable, empty, EMPTY, of } from 'rxjs';

  //This is now deprecated
  var delay = empty().pipe(delay(1000));     
  var delay2 = EMPTY.pipe(delay(1000));

Observable.empty() doesn't exist anymore.

Solution 4 - Javascript

In my case with Angular2 and rxjs, it worked with:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...

Solution 5 - Javascript

Several ways to create an Empty Observable:

They just differ on how you are going to use it further (what events it will emit after: next, complete or do nothing) e.g.:

  • Observable.never() - emits no events and never ends.
  • Observable.empty() - emits only complete.
  • Observable.of({}) - emits both next and complete (Empty object literal passed as an example).

Use it on your exact needs)

Solution 6 - Javascript

Yes, there is am Empty operator

Rx.Observable.empty();

For typescript, you can use from:

Rx.Observable<Response>.from([])

Solution 7 - Javascript

You can return Observable.of(empty_variable), for example

Observable.of('');

// or
Observable.of({});

// etc

Solution 8 - Javascript

Since all the answers are outdated, I will post the up to date answer here

In RXJS >= 6

import { EMPTY } from 'rxjs'
return EMPTY;

Solution 9 - Javascript

Or you can try ignoreElements() as well

Solution 10 - Javascript

RxJS 6

you can use also from function like below:

return from<string>([""]);

after import:

import {from} from 'rxjs';

Solution 11 - Javascript

Came here with a similar question, the above didn't work for me in: "rxjs": "^6.0.0", in order to generate an observable that emits no data I needed to do:

import {Observable,empty} from 'rxjs';
class ActivatedRouteStub {
  params: Observable<any> = empty();
}

Solution 12 - Javascript

Differents way to return empty observable :

  1. Observable.from({});
  2. Observable.of({});
  3. EMPTY

https://www.learnrxjs.io/learn-rxjs/operators/creation/empty

Solution 13 - Javascript

Try this

export class Collection{
public more (): Observable<Response> {
   if (this.hasMore()) {
     return this.fetch();
   }
   else{
     return this.returnEmpty(); 
   }            
  }
public returnEmpty(): any {
    let subscription = source.subscribe(
      function (x) {
       console.log('Next: %s', x);
    },
    function (err) {
       console.log('Error: %s', err);
    },
    function () {
       console.log('Completed');
    });
    }
  }
let source = Observable.empty();

Solution 14 - Javascript

You can return the empty observable with all different ways but challenge is to to return it with the expected type - Here is the way to create a empty observable with type -

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
return next.handle(this.setHeaders(req))
			.pipe(
				catchError((error: HttpErrorResponse) => {
        // you write your logic and return empty response if required
        return new Observable<HttpEvent<any>>();
            }));
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMurhaf SousliView Question on Stackoverflow
Solution 1 - JavascriptStephen LautierView Answer on Stackoverflow
Solution 2 - JavascriptAndrei PetrovView Answer on Stackoverflow
Solution 3 - JavascriptSimon_WeaverView Answer on Stackoverflow
Solution 4 - JavascriptMarcel TinnerView Answer on Stackoverflow
Solution 5 - JavascriptAndrii VerbytskyiView Answer on Stackoverflow
Solution 6 - JavascriptToan NguyenView Answer on Stackoverflow
Solution 7 - JavascriptChybieView Answer on Stackoverflow
Solution 8 - JavascriptMurhaf SousliView Answer on Stackoverflow
Solution 9 - JavascriptTuong LeView Answer on Stackoverflow
Solution 10 - JavascriptNourView Answer on Stackoverflow
Solution 11 - JavascriptCallatView Answer on Stackoverflow
Solution 12 - JavascriptSouhail HARRATIView Answer on Stackoverflow
Solution 13 - JavascriptJorawar SinghView Answer on Stackoverflow
Solution 14 - JavascriptviveksharmaView Answer on Stackoverflow