Zwróć pusty Observable

167

Funkcja more()ma zwrócić wynik Observablez żądania get

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

W takim przypadku mogę wykonać żądanie tylko wtedy, gdy hasMore()jest prawdziwe, w przeciwnym razie otrzymuję błąd w subscribe()funkcji subscribe is not defined, jak mogę zwrócić puste obserwowalne?

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

Aktualizacja

W RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 
Murhaf Sousli
źródło

Odpowiedzi:

130

W przypadku maszynopisu możesz określić ogólny parametr swojego pustego obserwowalnego w następujący sposób:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();
Andrei Petrov
źródło
26
To powinno być teraz import "EmptyObservable" from "rxjs/observable/EmptyObservable";, a następnie new EmptyObservable<Response>();.
87

Dzięki nowej składni RxJS 5.5+ wygląda to następująco:

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

Tylko jedna rzecz, o której należy pamiętać, empty()uzupełnia obserwowalne, więc nie uruchamia się nextw Twoim strumieniu, a jedynie kończy. Jeśli więc masz, na przykład, tapmogą nie zostać wyzwolone tak, jak chcesz (patrz przykład poniżej).

Natomiast of({})tworzy Observablei emituje następne z wartością, {}a następnie uzupełnia Observable.

Na przykład:

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();
Stephen Lautier
źródło
1
of('foo')emituje i natychmiast uzupełnia obserwowalne. rxviz.com/v/0oqMVW1o
SimplGy
@SimplGy tak, masz rację, mój błąd za używanie take(1)usunięty, aby uzyskać lepszą odpowiedź. @MatthijsWessels, tak i nie, właśnie przetestowałem to teraz, a jeśli to zrobisz, zwrócisz of()pełne obserwowalne bez emisjinext
Stephen Lautier,
Puste jest teraz przestarzałe, zamiast tego użyj EMPTY (używanego jako stała zamiast metody, patrz odpowiedź autorstwa Simon_Weaver).
EriF89
Pamiętaj, że of () nie emituje żadnej wartości. Jeśli chcesz taką, powinieneś podać dowolną wartość, nawet undefined lub null jest w porządku: of (null) emituje wartość (i procesy z metodami tap / subscribe), podczas gdy of () nie.
Maxim Georgievskiy
51

RxJS6 (bez zainstalowanego pakietu zgodności)

Jest teraz EMPTYstała i emptyfunkcja.

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

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

Observable.empty() już nie istnieje.

Simon_Weaver
źródło
Przewodnik po aktualizacji: github.com/ReactiveX/rxjs/blob/master/MIGRATION.md
Simon_Weaver
Jeśli masz już konflikt, taki jak empty()funkcja, możesz powiedzieć import { empty as rxEmpty }lub, import { empty as _empty }a następnie wykonać rxEmpty()lub _empty(). Oczywiście to dość niestandardowa czynność i tak naprawdę nie polecam tego, ale jestem pewien, że nie jestem jedynym, który był zaskoczony, że RxJS uważa, że ​​warto zaimportować funkcje takie jak ofi emptydo mojej przestrzeni nazw!
Simon_Weaver
1
uważaj, jeśli używasz Angulara, ponieważ jest też import { EMPTY } from "@angular/core/src/render3/definition";coś, czego nie chcesz. Więc jeśli otrzymujesz dziwne błędy, upewnij się, że nie importujesz ich przez pomyłkę.
Simon_Weaver,
Observable.empty()w rzeczywistości nadal istnieje, ale został wycofany na korzyść EMPTY.
Alexander Abakumov
39

W moim przypadku z Angular2 i rxjs działało z:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...
Marcel Tinner
źródło
7
import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
dołącz
otrzymuję taki błąd, czy muszę cokolwiek konfigurować w konfiguracji systemu? Nieobsługiwane odrzucenie obietnicy: (SystemJS) błąd XHR (404 nie znaleziono) ładowanie localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable.js Błąd: błąd XHR (404 nie znaleziono) ładowanie localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable. js
user630209
29

Tak, jest operator Empty

Rx.Observable.empty();

W przypadku maszynopisu możesz użyć from:

Rx.Observable<Response>.from([])
Toan Nguyen
źródło
Dostaję Rx.Observable<{}>nie można przypisać do Observable<Response>, próbowałem, Rx.Observable<Response>.empty()ale to nie zadziałało
Murhaf Sousli
Zmieniłem typ powrotu na Observable<any>i zadziałało, dzięki kolego.
Murhaf Sousli
2
Powinien być Rx.Observable.from([])bez <Response>. W przeciwnym razie zostanie wyświetlony błąd „oczekiwano wyrażenia”.
Andriy Tolstoy
2
Możesz także użyć Rx.Observable.of([]).
Andriy Tolstoy
1
@AndriyTolstoy Nie jestem pewien, czy to jest równoważne. W programie Observable.of([])jest emitowana jedna wartość ( []), a następnie strumień się kończy. Gdy Observable.from([])nie jest emitowana żadna wartość, strumień kończy się natychmiast.
Pac0
24

Kilka sposobów na utworzenie pustego obserwowalnego:

Oni po prostu różnią się, w jaki sposób masz zamiar go używać dalej (co wydarzenia będzie emitować po: next, completelub do nothing), np:

  • Observable.never() - nie emituje żadnych wydarzeń i nigdy się nie kończy.
  • Observable.empty()- emituje tylko complete.
  • Observable.of({})- emituje oba nexti complete(jako przykład podano pusty literał obiektu).

Użyj go dokładnie według swoich potrzeb)

Andrii Verbytskyi
źródło
13

Możesz na przykład zwrócić Observable.of (empty_variable)

Observable.of('');

// or
Observable.of({});

// etc
Chybie
źródło
2

Albo można spróbować ignoreElements()także

Tuong Le
źródło
1

RxJS 6

możesz użyć również z funkcji jak poniżej:

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

po imporcie:

import {from} from 'rxjs';
Nour
źródło
2
Spowoduje to utworzenie Observable, który zapewni jeden element (pusty ciąg), więc nie będzie wyglądać na właściwą odpowiedź na to konkretne pytanie.
BrunoJCM
1

Przyszedłem tutaj z podobnym pytaniem, powyższe nie zadziałało dla mnie "rxjs": "^6.0.0"w:, aby wygenerować obserwowalny, który nie emituje żadnych danych, które musiałem zrobić:

import {Observable,empty} from 'rxjs';
class ActivatedRouteStub {
  params: Observable<any> = empty();
}
Callat
źródło
0

Spróbuj tego

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();
Jorawar Singh
źródło