<commit_before>import { AfterViewInit, Component, HostListener, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject'
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';

import { HeroFilter } from '../hero-filter/hero-filter.component';
import { HeroService } from '../../services';
import { WindowService } from '../../../core';
import { Hero } from '../../models';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.scss']
})
export class HeroesComponent implements OnInit, AfterViewInit {
  heroes: Observable<Hero[]>;
  canMoveToTop = false;
  private filter = new Subject<HeroFilter>();

  constructor(private heroService: HeroService, private windowService: WindowService) {
  }

  @HostListener('window:scroll', ['$event'])
    trackPosition(event) {
      this.canMoveToTop =  document.body.scrollTop > 0;
    }

  ngOnInit() {
    this.heroes = this.filter
      .switchMap(filter => filter
        ? this.heroService.searchHeroes(filter.universe, filter.role, filter.terms)
        : Observable.of<Hero[]>([]))
      .catch(error => {
        // TODO: add real error handling
        console.log(error);
        return Observable.of<Hero[]>([]);
      });
  }

  ngAfterViewInit() {
    this.filterHeroes(new HeroFilter());
  }

  filterHeroes (filter: HeroFilter) {
    this.filter.next(filter);
  }<commit_msg>Add debounce time and distinct before search<commit_after>import { AfterViewInit, Component, HostListener, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';

import { HeroFilter } from '../hero-filter/hero-filter.component';
import { HeroService } from '../../services';
import { WindowService } from '../../../core';
import { Hero } from '../../models';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.scss']
})
export class HeroesComponent implements OnInit, AfterViewInit {
  heroes: Observable<Hero[]>;
  canMoveToTop = false;
  private filter = new Subject<HeroFilter>();

  constructor(private heroService: HeroService, private windowService: WindowService) {
  }

  @HostListener('window:scroll', ['$event'])
    trackPosition(event) {
      this.canMoveToTop =  document.body.scrollTop > 0;
    }

  ngOnInit() {
    this.heroes = this.filter
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap(filter => filter
        ? this.heroService.searchHeroes(filter.universe, filter.role, filter.terms)
        : Observable.of<Hero[]>([]))
      .catch(error => {
        // TODO: add real error handling
        console.log(error);
        return Observable.of<Hero[]>([]);
      });
  }

  ngAfterViewInit() {
    this.filterHeroes(new HeroFilter());
  }

  filterHeroes (filter: HeroFilter) {
    this.filter.next(filter);
  }
{'fraction_non_alphanumeric': 0.1560991309945285, 'fraction_numerical': 0.0016092693916961698, 'mean_word_length': 3.6457399103139014, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3951712', 'n_tokens_mistral': 958, 'n_tokens_neox': 946, 'n_words': 198}