Getting a Property 'filter' does not exist on type 'OperatorFunction<any, any>' error in Angular

Viewed 473

I am working on a simple youtube search as you type app and I am getting a "Property 'filter' does not exist on type 'OperatorFunction<any, any>' error. I nested the debounce and all within the .pipe, but if I delete the filer I get the same error for the deBouncetime and .do. I have debounceTime imported and used. but VScode has it greyed out for some reason. I have tried to also import filter from "rxjs/operators", but that did not help. Any help will be much appreciated.

import { Component, OnInit } from '@angular/core';
import {Output} from '@angular/core';
import { EventEmitter } from '@angular/core';
import {ElementRef} from '@angular/core';
import {Observable} from 'rxjs';
import {map, debounceTime} from 'rxjs/operators';
import 'rxjs/add/operator/filter'
import { fromEvent } from 'rxjs';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/switch';
import { SearchResult } from '../search-result.model';
import {YoutubesearchService} from '../youtubesearch.service';


@Component({
  selector: 'app-search-box',
  templateUrl: './search-box.component.html',
  styleUrls: ['./search-box.component.css']
})
export class SearchBoxComponent implements OnInit {
  @Output() loading: EventEmitter<boolean> = new EventEmitter<boolean>();
  @Output() results: EventEmitter<SearchResult[]> = new EventEmitter<SearchResult[]>();
  constructor(private youtube: YoutubesearchService, private el: ElementRef ) { }

  ngOnInit(): void {
    // convert the `keyup` event into an observable stream
    fromEvent(this.el.nativeElement, 'keyup')
      .pipe(map((e: any) => e.target.value) // extract the value of the input
        .filter((text: string) => text.length > 1) // filter out if empty
        .debounceTime(250)                         // only once every 250ms
        .do(() => this.loading.emit(true))         // enable loading
        // search, discarding old events if new input comes in
        .map((query: string) => this.youtube.search(query))
        .switch())
      // act on the return of the search
      .subscribe(
        (results: SearchResult[]) => { // on sucesss
          this.loading.emit(false);
          this.results.emit(results);
        },
        (err: any) => { // on error
          console.log(err);
          this.loading.emit(false);
        },
        () => { // on completion
          this.loading.emit(false);
        }
      );
  }
}

1 Answers

I believe your problem is that you are using an old syntax.

import { Component, OnInit, Output, EventEmitter, ElementRef } from '@angular/core';
import {Observable, fromEvent} from 'rxjs';
import {map, debounceTime, filter, tap, switchMap} from 'rxjs/operators';
import { SearchResult } from '../search-result.model';
import {YoutubesearchService} from '../youtubesearch.service';


@Component({
  selector: 'app-search-box',
  templateUrl: './search-box.component.html',
  styleUrls: ['./search-box.component.css']
})
export class SearchBoxComponent implements OnInit {
  @Output() loading: EventEmitter<boolean> = new EventEmitter<boolean>();
  @Output() results: EventEmitter<SearchResult[]> = new EventEmitter<SearchResult[]>();
  constructor(private youtube: YoutubesearchService, private el: ElementRef ) { }

  ngOnInit(): void {
    // convert the `keyup` event into an observable stream
    fromEvent(this.el.nativeElement, 'keyup')
      .pipe(
         map((e: any) => e.target.value), // extract the value of the input
         filter((text: string) => text.length > 1), // filter out if empty
         debounceTime(250),                         // only once every 250ms
         tap(() => this.loading.emit(true)),         // enable loading
        // search, discarding old events if new input comes in
         switchMap((query: string) => this.youtube.search(query)),
         )
      // act on the return of the search
      .subscribe(
        (results: SearchResult[]) => { // on sucesss
          this.loading.emit(false);
          this.results.emit(results);
        },
        (err: any) => { // on error
          console.log(err);
          this.loading.emit(false);
        },
        () => { // on completion
          this.loading.emit(false);
        }
      );
  }
}

Try above

Related