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

JavascriptAngularRxjs

Javascript Problem Overview


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 ?

Javascript Solutions


Solution 1 - Javascript

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: > > 1. rxjs/operators: Contains all pipeable operators. > > import { map, filter, scan } from 'rxjs/operators'; > > 2. rxjs: Contains creation methods, types, schedulers, and utilities. > > import { Observable, Subject, asapScheduler, pipe, of, from, > interval, merge, fromEvent } from 'rxjs';

Solution 2 - Javascript

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

Solution 3 - Javascript

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

Solution 4 - Javascript

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

Solution 5 - Javascript

The easiest way to work around that is to just

npm install rxjs-compat 

which will make any version differences magically go away!

Solution 6 - Javascript

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

Solution 7 - Javascript

transform(value: any,  args?: any): unknown {
  if(!args)     
    return value;
  return value.filter(item => item.title)
}

transform(value: any,  args?: any): unknown {
  if(!args)     
    return value;
  return value.filter(item => item.title)
}

If show filter error use like this, mainly value:any is working perfectly.

Solution 8 - Javascript

Please check the type of Event here -> .filter((event:Event)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionritz078View Question on Stackoverflow
Solution 1 - JavascriptcandidJView Answer on Stackoverflow
Solution 2 - JavascriptPetr HavlicekView Answer on Stackoverflow
Solution 3 - JavascriptIan SamzView Answer on Stackoverflow
Solution 4 - JavascriptNathaniel HView Answer on Stackoverflow
Solution 5 - JavascriptwendellmvaView Answer on Stackoverflow
Solution 6 - JavascriptMosia ThaboView Answer on Stackoverflow
Solution 7 - JavascriptjagadishView Answer on Stackoverflow
Solution 8 - JavascriptshyvijayView Answer on Stackoverflow