Hi I am using Angular 2 final with router 3.0. I want to filter the events that are emitted from this.router.events
What I want to do :
import 'rxjs/operator/filter';
//...
this.router.events
.filter((event:Event) => event instanceof NavigationEnd)
.subscribe(x => console.log(x))
event
can be instanceOf NavigationEnd
, NavigationStart
or RoutesRecognized
but I want only NavigationEnd
. But I get an error that
Property 'filter' does not exist on type Observable<Event>
during compile time.
When i import the whole rxjs
library the error disappears. What should I import to make it work without loading the full rxjs library ?
UPDATE
For RXJS 5.x
version:
import 'rxjs/add/operator/filter';
For RXJS 6.x
version:
import { filter } from 'rxjs/operators';
The following rules have been designed by the RxJS team to help
JavaScript developers refactor import paths:
rxjs/operators
: Contains all pipeable operators.
import { map, filter, scan } from 'rxjs/operators';
rxjs
: Contains creation methods, types, schedulers, and utilities.
import { Observable, Subject, asapScheduler, pipe, of, from,
interval, merge, fromEvent } from 'rxjs';
There are several possible fixes for this scenario.
1) Use pipeable operators
Pipeable operators are meant to be a better approach for pulling in just the operators you need than the "patch" operators found in rxjs/add/operator/*
import { filter } from 'rxjs/operators';
// ..
this.router.events.pipe(
filter((event:Event) => event instanceof NavigationEnd)
).subscribe(x => console.log(x))
2) Use 'rxjs/add/operator/filter'
Change the import statement to import 'rxjs/add/operator/filter'
. This will modify Observable.prototype
and add filter
method to an every instance of the Observable class.
There are two consequences:
- it is enough to execute the import statement just once per the application
- in a shared library/npm package this might bring some confusion to a library consumer (
filter()
method will magically appear under Observable
while using the library)
3) Leave the operator import but change how it is called
The statement import 'rxjs/operator/filter'
is perfectly valid. It will import just the operator. This approach will not mess with the Observable.prototype
. On downside it will make it more difficult to chain several operators.
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));
More details: Pipeable Operators
Angular Update(5.x to 6.x) also comes with update of rxjs from 5.x to 6.x
So simply add
import { filter } from 'rxjs/operators';
then
this.router.events.pipe(
filter((event:Event) => event instanceof NavigationEnd)
).subscribe(x => console.log(x))
Hope That helps someone
After updating to Rxjs 6 with 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();
The easiest way to work around that is to just
npm install rxjs-compat
which will make any version differences magically go away!
PLEASE NOTE:
I would like to mention a few things that the above answers are not addressing.
RxJs is a standalone library, and for that matter its operations are standalone methods as well. map, filter etc are operator methods that are not accessed through an object. Remember that you import them seperately.
So for example you cannot import { filter}
and want to access it through the router
object. That will never work because a router
object is an angular specific class instance somewhere in the API's. Angular provides a pipe()
method that allows you to register methods that must be chained in the process before moving to the next method within the router
that aren't part of the router
object.
ALWAYS REMEMBER THAT
Please check the type of Event here -> .filter((event:Event)