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);
   }
)

Update

In RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 

11 Answers

97
Andrei Petrov On Best Solutions

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

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();
28
Toan Nguyen On

Yes, there is am Empty operator

Rx.Observable.empty();

For typescript, you can use from:

Rx.Observable<Response>.from([])
9
Chybie On

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

Observable.of('');

// or
Observable.of({});

// etc
0
Jorawar Singh On

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();
2
Tuong Le On

Or you can try ignoreElements() as well

34
Marcel Tinner On

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

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...
35
Stephen Lautier On

With the new syntax e.g. rxjs 5.5+, this becomes as following:

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

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

empty();
of({});

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

whereas of({}) creates an observable and emits next with a value of {}, it won't complete the observable alone, perhaps you should do of({}).pipe(take(1)) to emit and complete.

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();
23
Simon_Weaver On

RxJS6 (without compatibility package installed)

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

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

  var delay = empty().pipe(delay(1000));     
  var delay2 = EMPTY.pipe(delay(1000));

Observable.empty() doesn't exist anymore.

0
Nour On

RxJS 6

you can use also from function like below:

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

after import:

import {from} from 'rxjs';
11
Andrii Verbytskyi On

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)

0
Callat On

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();
}