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; 

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

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


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.



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

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([])

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)


13

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

Observable.of('');

// or
Observable.of({});

// etc


1

RxJS 6

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

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

après l'importation:

import {from} from 'rxjs';

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

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();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.