Dariux
Dariux

Reputation: 4233

Counting keypresses per second with angular 2 Rxjs

/**
 * Created by darius on 02/04/16.
 */
import { Component } from 'angular2/core';
import { Observable } from 'rxjs/Rx';


@Component({
  styles: [ require('../../style.css') ],
  selector: 'keypresses-per-second',

  template: `

    <div class="block">

      <input  type="text" (keypress)="onKeypress($event)">

      {{keypresses}} <br>
      <input type="text" (keypress)="onKeypressReact($event)">
      {{keypressesReactive}}
    </div>
  `
})

export class KeypressesPerSecond {

  ngOnInit() {

    this.nonReactive();

    this.reactiveWay();
  }

  // not reactive
  keypresses = '';
  counter = 0;
  secondsPassed = 0;

  nonReactive(){

    var self = this;

    var int = setInterval(function(){

      console.log(self.counter, 'counter in non reactive')
      self.keypresses += self.counter + ', ';
      self.counter = 0;
      self.secondsPassed++
      if (self.secondsPassed > 30) {
        clearInterval(int);
      }
    }, 1000);
  }

  onKeypress($event){
    console.log($event.keyCode);
    this.counter++;
  }
  // end not reactive

  onKeypressReact() {}

  keypressesReactive = '';
  reactiveCount = 0;

  reactiveWay() {

    console.log('reactive way')

    const keypressObservable$ = Observable.create(observer => {

      // from template
      this.onKeypressReact = () => { observer.next('press'); };
    });


    keypressObservable$.subscribe(function(event) {
      self.reactiveCount++;
    });

    var self = this;

    var timer$ = Observable.create(function(observer){

      // is subscribed to this observable
      var subscribed = true;
      var int = setInterval(function() {

        if (subscribed) {
          observer.next(self.reactiveCount);
          self.reactiveCount = 0;
        }

        if (self.secondsPassed > 30) {
          observer.complete();
          clearInterval(int)
        }

      }, 1000);

    })


    timer$.subscribe(
      function (x) {
        console.log('Nextzz: %s', x);
        self.keypressesReactive += x + ', ';
      });

  }

}

I tried to write reactive and non reactive way of keypresses counter. Take a look at function reactiveWay()

it works, but I think there might be something wrong.

I done excersizes in there http://reactivex.io/learnrx/

and there was lot of mapping.

It feels like I I had to map the time event to sequence of key events happened per second. But do not get how could I map those.

Something like

// doing this way we could removed some code from timer$, we just need to get an event
var kps$ = timer$.concatMap(function(time) {

  var sum = keypressObservable$.takeUntil(timer$)
    .reduce(function (acc, cur) {
      return acc + cur;
    })

  console.log('sum', sum);

  return sum;
})

// this works, counts the keypresses, but only when pressing at least 1. 
kps$.subscribe(
  function (x) {
    console.log('kps next', x);
    self.keypressesReactive += x + ', ';
  });

How do I force kps$ to emit 0 sum when no keypresses done in the second if I use the kps$?

Update

Based on the answer, I have done this.

var source = Observable.fromEvent(document.body, 'keypress');

var delayedSource = source.delay(1000);


var obs = source

  .buffer(delayedSource)


  .map((clickBuffer) => {
    return clickBuffer.length;
  })

But when I subscribe to the obs, I do not get event each second containing 0 value still. When I press some keys in a second, then I get the number of keys pressed and another event of 0. And then events stop until I press keys again. What do I need to modify so I get event each second?

Upvotes: 1

Views: 1589

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202196

I think that you could leverage the buffer operator. It allows to buffer events and sends them after an amount of time. You could then map this list of events to its length.

var source = Observable.fromEvent(document.body, 'keyup');

var obs = source
     .bufferTime(1000).map((clickBuffer) => {
       return clickBuffer.length;
     });

obs.subscribe((num) => {
  // Get the number of pressed keys per second
});

See these links:

Upvotes: 3

Related Questions