Renvoyer un observable vide

167

La fonction more()est censée renvoyer un à Observablepartir d'une requête 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();
          }
       );
    }
}

Dans ce cas, je ne peux faire une requête que si hasMore()c'est vrai, sinon j'obtiens une erreur sur la subscribe()fonction subscribe is not defined, comment puis-je retourner une observable vide?

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

Mettre à jour

Dans RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 
Murhaf Sousli
la source

Réponses:

130

Pour le typographie, vous pouvez spécifier le paramètre générique de votre observable vide comme ceci:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();
Andrei Petrov
la source
26
Cela devrait être maintenant import "EmptyObservable" from "rxjs/observable/EmptyObservable";, alors new EmptyObservable<Response>();.
87

Avec la nouvelle syntaxe de RxJS 5.5+, cela devient comme suit:

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

Juste une chose à garder à l'esprit, empty()complète l'observable, donc il ne se déclenchera pas nextdans votre flux, mais se terminera seulement. Donc si vous avez, par exemple,tap ils pourraient ne pas se déclencher comme vous le souhaitez (voir un exemple ci-dessous).

Alors que of({})crée un Observableet émet ensuite avec une valeur de {}, puis il complète leObservable .

Par exemple:

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
la source
1
of('foo')émet et complète l'observable immédiatement. rxviz.com/v/0oqMVW1o
SimplGy
@SimplGy oui vous avez raison, mon mauvais usage est take(1)supprimé pour une meilleure réponse. @MatthijsWessels, oui et non, vient de tester cela maintenant et si vous le faites, vous of()retournerez un observable complet sans émettrenext
Stephen Lautier
empty est maintenant obsolète, utilisez EMPTY à la place (utilisé comme une constante plutôt que comme une méthode, voir la réponse de Simon_Weaver).
EriF89 le
Veuillez garder à l'esprit que of () n'émet aucune valeur. Si vous en voulez un, vous devez fournir n'importe quelle valeur, même indéfinie ou null est ok pour cela: of (null) émet la valeur (et les processus avec les méthodes tap / subscribe), tandis que of () ne le fait pas.
Maxim Georgievskiy
51

RxJS6 (sans package de compatibilité installé)

Il y a maintenant une EMPTYconstante et une emptyfonction.

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

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

Observable.empty() n'existe plus.

Simon_Weaver
la source
Guide de mise à jour: github.com/ReactiveX/rxjs/blob/master/MIGRATION.md
Simon_Weaver
Si vous avez déjà un conflit comme une empty()fonction, vous pouvez dire import { empty as rxEmpty }ou import { empty as _empty }puis faire rxEmpty()ou _empty(). Bien sûr, c'est une chose assez inhabituelle à faire et je ne le recommande pas vraiment, mais je ne suis pas le seul à avoir été surpris que RxJS pense qu'il vaut la peine d'importer des fonctions comme ofet emptydans mon espace de noms!
Simon_Weaver
1
attention si vous utilisez Angular car il y a aussi import { EMPTY } from "@angular/core/src/render3/definition";ce qui n'est pas du tout ce que vous voulez. Donc, si vous rencontrez des erreurs étranges, assurez-vous de ne pas l'importer par erreur.
Simon_Weaver
Observable.empty()en fait existe encore , mais il est dépréciée en faveur EMPTY.
Alexander Abakumov
39

Dans mon cas avec Angular2 et rxjs, cela fonctionnait avec:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...
Marcel Tinner
la source
7
inclure avecimport {EmptyObservable} from 'rxjs/observable/EmptyObservable';
Kildareflare
obtenir une erreur comme celle-ci, dois-je configurer quelque chose dans la configuration système? Rejet de la promesse non gérée: Erreur XHR (SystemJS) (404 introuvable) lors du chargement de l' hôte local: 9190 / node_modules / rxjs / Observable / EmptyObservable.js Erreur: erreur XHR (404 introuvable) lors du chargement de l' hôte local: 9190 / node_modules / rxjs / Observable / EmptyObservable. js
user630209
29

Oui, il y a un opérateur vide

Rx.Observable.empty();

Pour dactylographié, vous pouvez utiliser from:

Rx.Observable<Response>.from([])
Toan Nguyen
la source
Je ne suis Rx.Observable<{}>pas assignable à Observable<Response>, j'ai essayé Rx.Observable<Response>.empty()mais ça n'a pas fonctionné
Murhaf Sousli
J'ai changé le type de retour Observable<any>et cela a fonctionné, merci mon pote.
Murhaf Sousli
2
Cela devrait être Rx.Observable.from([])sans <Response>. Sinon, obtenir une erreur "expression attendue".
Andriy Tolstoy
2
Vous pouvez également utiliser Rx.Observable.of([]).
Andriy Tolstoy
1
@AndriyTolstoy Je ne suis pas sûr que ce soit équivalent. Dans Observable.of([]), il y a une valeur émise ( []), puis le flux se termine. Avec Observable.from([]), aucune valeur n'est émise, le flux se termine immédiatement.
Pac0
24

Plusieurs façons de créer un observable vide:

Ils diffèrent seulement sur la façon dont vous allez utiliser davantage (quels événements il émettra après: next, completeou do nothing) , par exemple:

  • Observable.never() - n'émet aucun événement et ne se termine jamais.
  • Observable.empty()- émet uniquement complete.
  • Observable.of({})- émet à la fois nextet complete(littéral d'objet vide passé comme exemple).

Utilisez-le sur vos besoins exacts)

Andrii Verbytskyi
la source
13

Vous pouvez renvoyer Observable.of (empty_variable), par exemple

Observable.of('');

// or
Observable.of({});

// etc
Chybie
la source
2

Ou tu peux ignoreElements()aussi essayer

Tuong Le
la source
1

RxJS 6

vous pouvez également utiliser une fonction comme ci-dessous:

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

après l'importation:

import {from} from 'rxjs';
Nour
la source
2
Cela créera un observable qui fournira un élément (une chaîne vide), donc cela ne ressemble pas à une réponse correcte à cette question spécifique.
BrunoJCM
1

Je suis venu ici avec une question similaire, ce qui précède n'a pas fonctionné pour moi dans:, "rxjs": "^6.0.0"afin de générer un observable qui n'émet aucune donnée que je devais faire:

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

Essaye ça

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
la source