Retornar um Observable vazio

167

A função more()deve retornar um Observablede uma solicitação 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();
          }
       );
    }
}

Nesse caso, só posso fazer uma solicitação se hasMore()for verdadeira; caso contrário, recebo um erro na subscribe()função subscribe is not defined, como posso retornar um observável vazio?

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

Atualizar

No RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 
Murhaf Sousli
fonte

Respostas:

130

Para texto datilografado, você pode especificar parâmetros genéricos do seu observável vazio como este:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();
Andrei Petrov
fonte
26
Agora deve ser import "EmptyObservable" from "rxjs/observable/EmptyObservable";então new EmptyObservable<Response>();.
87

Com a nova sintaxe do RxJS 5.5+, isso se torna o seguinte:

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

Apenas uma coisa a ter em mente: empty()conclui o observável, para que não seja acionado nextno seu fluxo, mas apenas é concluído. Portanto, se você tiver, por exemplo, tapeles podem não ser acionados como você deseja (veja um exemplo abaixo).

Considerando que of({})cria um Observablee emite a seguir com um valor de {}e, em seguida, conclui o Observable.

Por exemplo:

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
fonte
1
of('foo')emite e completa o observável imediatamente. rxviz.com/v/0oqMVW1o
SimplGy
@ SimplGy sim, você está correto, meu mau uso foi take(1)removido para uma resposta melhor. @MatthijsWessels, sim e não, apenas testou este agora e se o fizer of()irá retornar um observável completa sem emitirnext
Stephen Lautier
Agora vazio está obsoleto, use VAZIO (usado como uma constante e não como um método, veja a resposta por Simon_Weaver).
EriF89 24/04
Lembre-se de que () não emite nenhum valor. Se você deseja um, deve fornecer qualquer valor, mesmo que indefinido ou nulo seja aceitável: of (null) emite o valor (e processa com métodos de toque / assinatura), enquanto que () não.
Maxim Georgievskiy
51

RxJS6 (sem pacote de compatibilidade instalado)

Agora há uma EMPTYconstante e uma emptyfunção.

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

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

Observable.empty() não existe mais.

Simon_Weaver
fonte
Guia de atualização: github.com/ReactiveX/rxjs/blob/master/MIGRATION.md
Simon_Weaver
Se você já tem um conflito como uma empty()função, pode dizer import { empty as rxEmpty }or import { empty as _empty }e, em seguida, rxEmpty()or or _empty(). Claro que isso é uma coisa bastante fora do padrão e não estou recomendando, mas tenho certeza de que não sou a única surpresa que o RxJS acha que vale a pena importar funções como ofe emptypara o meu espaço para nome!
Simon_Weaver 25/05
1
cuidado ao usar o Angular, porque também existe o import { EMPTY } from "@angular/core/src/render3/definition";que você não quer. Portanto, se você estiver recebendo erros estranhos, verifique se não está importando isso por engano.
Simon_Weaver 11/01/19
Observable.empty()na verdade ainda existe, mas foi preterido em favor de EMPTY.
Alexander Abakumov
39

No meu caso com Angular2 e rxjs, ele trabalhou com:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...
Marcel Tinner
fonte
7
incluí-lo comimport {EmptyObservable} from 'rxjs/observable/EmptyObservable';
Kildareflare
recebendo erro como este, preciso configurar alguma coisa na configuração do sistema? Rejeição de promessa não tratada: Erro XHR (SystemJS) (404 não encontrado) ao carregar localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable.js Erro: Erro XHR (404 não encontrado) ao carregar localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable. js
user630209
29

Sim, existe um operador Vazio

Rx.Observable.empty();

Para texto datilografado, você pode usar from:

Rx.Observable<Response>.from([])
Toan Nguyen
fonte
Estou recebendo Rx.Observable<{}>não é atribuível Observable<Response>, tentei, Rx.Observable<Response>.empty()mas não funcionou #
Murhaf Sousli
Mudei o tipo de retorno para Observable<any>e funcionou, obrigado companheiro.
Murhaf Sousli
2
Deveria estar Rx.Observable.from([])sem <Response>. Caso contrário, obter um erro "expressão esperada".
Andriy Tolstoy
2
Você também pode usar Rx.Observable.of([]).
precisa saber é o seguinte
1
@AndriyTolstoy Não tenho certeza se isso é equivalente. Em Observable.of([]), existe um valor emitido ( []) e o fluxo é concluído. Com Observable.from([]), nenhum valor é emitido, o fluxo é concluído imediatamente.
Pac0
24

Várias maneiras de criar um Observável Vazio:

Eles só diferem em como você está indo para usá-lo ainda mais (os eventos que ele irá emitir depois: next, completeou do nothing) por exemplo:

  • Observable.never() - não emite eventos e nunca acaba.
  • Observable.empty()- emite apenas complete.
  • Observable.of({})- emite ambos nexte complete(literal de objeto vazio passado como exemplo).

Use-o em suas necessidades exatas)

Andrii Verbytskyi
fonte
13

Você pode retornar Observable.of (empty_variable), por exemplo

Observable.of('');

// or
Observable.of({});

// etc
Chybie
fonte
2

Ou você pode tentar ignoreElements()também

Tuong Le
fonte
1

RxJS 6

você também pode usar a partir da função como abaixo:

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

após a importação:

import {from} from 'rxjs';
Nour
fonte
2
Isso criará um Observable que fornecerá um elemento (uma sequência vazia), para que não pareça uma resposta adequada para essa pergunta específica.
BrunoJCM
1

Vim aqui com uma pergunta semelhante, o exemplo acima não funcionou para mim "rxjs": "^6.0.0"em:, a fim de gerar um observável que não emite dados que eu precisava fazer:

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

Tente isto

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
fonte