web-dev-qa-db-fra.com

La propriété 'filtre' n'existe pas sur le type 'Observable <Event>'

Bonjour, j'utilise Angular 2 final avec le routeur 3.0. Je souhaite filtrer les événements émis par this.router.events

Ce que je veux faire :

import 'rxjs/operator/filter';

//...

this.router.events
  .filter((event:Event) => event instanceof NavigationEnd)
  .subscribe(x => console.log(x))

event peut être instanceOf NavigationEnd, NavigationStart ou RoutesRecognized mais je ne veux que NavigationEnd. Mais je reçois une erreur qui

Property 'filter' does not exist on type Observable<Event>

pendant le temps de compilation.

Lorsque j'importe la bibliothèque rxjs entière, l'erreur disparaît. Que dois-je importer pour que cela fonctionne sans charger la bibliothèque complète rxjs?

53
ritz078

[~ # ~] met à jour [~ # ~]

Pour RXJS 5.x version:

import 'rxjs/add/operator/filter';

Pour RXJS 6.xversion :

import { filter } from 'rxjs/operators';

Les règles suivantes ont été conçus par l'équipe RxJS pour aider les développeurs JavaScript à refactoriser les chemins d'importation:

  1. rxjs/operators: Contient tous les opérateurs pouvant être canalisés.

import { map, filter, scan } from 'rxjs/operators';

  1. rxjs: contient les méthodes de création, les types, les planificateurs et les utilitaires.

import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent } from 'rxjs';

96
candidJ

Plusieurs solutions sont possibles pour ce scénario.

1) Utiliser des opérateurs canalisables

Les opérateurs pipeables sont censés être une meilleure approche pour attirer uniquement les opérateurs dont vous avez besoin que les opérateurs "correctifs" trouvés dans rxjs/add/operator/*

import { filter } from 'rxjs/operators';

// ..

 this.router.events.pipe(
   filter((event:Event) => event instanceof NavigationEnd)
 ).subscribe(x => console.log(x))

2) Utilisez 'rxjs/add/operator/filter'

Modifiez l'instruction d'importation en import 'rxjs/add/operator/filter'. Ceci modifiera Observable.prototype Et ajoutera la méthode filter à chaque instance de la classe Observable.

Il y a deux conséquences:

  • il suffit d'exécuter l'instruction d'importation une seule fois par application
  • dans un paquet bibliothèque partagée/npm, cela pourrait semer la confusion chez un consommateur de bibliothèque (la méthode filter() apparaîtra comme par magie sous Observable lors de l'utilisation de la bibliothèque)

3) Laissez l’importation de l’opérateur, mais changez le nom.

La déclaration import 'rxjs/operator/filter' Est parfaitement valide. Cela importera seulement l'opérateur. Cette approche ne va pas déconner avec le Observable.prototype. En revanche, il sera plus difficile d’enchaîner plusieurs opérateurs.

import 'rxjs/operator/filter'; // This is valid import statement.
                               // It will import the operator without 
                               // modifying Observable prototype
// ..

// Change how the operator is called
filter.call(
   this.router.events, 
   (event:Event) => event instanceof NavigationEnd
).subscribe(x => console.log(x));

Plus de détails: opérateurs pipeables

33
Petr Havlicek

Mise à jour angulaire (5.x à 6.x) vient également avec la mise à jour de rxjs de 5.x à 6.x Il suffit donc d’ajouter

import { filter } from 'rxjs/operators';

ensuite

this.router.events.pipe(
  filter((event:Event) => event instanceof NavigationEnd)
).subscribe(x => console.log(x))

J'espère que ça aide quelqu'un

15
Ian Samz

Après la mise à jour vers Rxjs 6 avec Angular 6 upgrade

import { map, filter, scan } from 'rxjs/operators';

...
this.registrationForm.valueChanges
      .pipe(
        filter(() => this.registrationForm.valid),
        map((registrationForm: any) => {
          this.registrationVm.username = registrationForm.username;
          this.registrationVm.password = registrationForm.password;
          this.registrationVm.passwordConfirm = registrationForm.passwordConfirm;
        })
      )
      .subscribe();
7
Nathaniel H

Le moyen le plus simple de contourner ce problème est de simplement

npm install rxjs-compat 

ce qui fera disparaître toutes les différences de version par magie!

4
wendellmva