<commit_before>import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/skip';
import 'rxjs/add/operator/takeUntil';
import { Injectable, NgZone } from '@angular/core';
import { Effect, Actions, toPayload } from '@ngrx/effects';
import { Action, Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { from } from 'rxjs/observable/from';
import * as firebase from 'firebase';
import * as eventActions from './events.actions';
import { Event } from './events.model';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { getEventsState, State } from '../../app.reducers';
import { getEntities } from './events.reducer';
import { SetCenterAction } from '../map/map.actions';

const database = firebase.database();

const eventsRef = database.ref('events');

// clearAndRandomiseEvents();

function clearAndRandomiseEvents() {
  let clearUpdates = {};
  clearUpdates['/events'] = {};
  firebase.database().ref().update(clearUpdates)
    .then(() => {
      let updates = {};

      for (let i = 0; i < 20; i++) {
        let newEventKey = eventsRef.push().key;
        updates['/events/' + newEventKey] = <Event> {
          id: null,
          title: newEventKey,
          location: {
            description: null,
            coords: {
              lat: getRandom(-36, -44),
              lng: getRandom(170, 182),
            },
            bounds: null,
            place_id: null,
          },
          imageUrl: 'https://unsplash.it/400/300/?random&asdf=' + Math.random(),
          description: `
          Lorem Ipsum is simply dummy text of the printing and typesetting industry. 
          Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, 
          when an unknown printer took a galley of type and scrambled it to make a type specimen book. 
          It has survived not only five centuries, but also the leap into electronic typesetting,
          remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset 
          sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like
          Aldus PageMaker including versions of Lorem Ipsum.`
        };
      }
      firebase.database().ref().update(updates);
    });

  function getRandom(min, max) {
    return Math.random() * (max - min) + min;
  }
}

/**
 * Effects offer a way to isolate and easily test side-effects within your
 * application.
 * The `toPayload` helper function returns just
 * the payload of the currently dispatched action, useful in
 * instances where the current state is not necessary.
 *
 * Documentation on `toPayload` can be found here:
 * https://github.com/ngrx/effects/blob/master/docs/api.md#topayload
 *
 * If you are unfamiliar with the operators being used in these examples, please
 * check out the sources below:
 *
 * Official Docs: http://reactivex.io/rxjs/manual/overview.html#categories-of-operators
 * RxJS 5 Operators By Example: https://gist.github.com/btroncone/d6cf141d6f2c00dc6b35
 */
@Injectable()
export class EventsEffects {

  @Effect()
  select$: Observable<Action> = this.actions$
    .ofType(eventActions.SELECT)
    .map(toPayload)
    .switchMap((id) =>
      this.store.select(getEventsState)
        .map(getEntities)
        .map((entities) => entities[id])
        .first()
    )
    .filter((event) => event && !!event.location)
    .map((event) => new SetCenterAction(event.location));

  @Effect()
  init$: Observable<Action> = this.actions$
    .ofType(eventActions.INIT)
    .map(toPayload)
    .startWith(null)
    .first()
    .switchMap(() => {
      let replay: ReplaySubject<Action[]> = new ReplaySubject();

      // TODO child updated / added events?
      eventsRef.on('value', (snapshot) => this.handleValue(snapshot, replay));
      eventsRef.on('child_removed', (snapshot) => this.handleRemove(snapshot, replay));

      return replay;
    })
    .mergeMap((actions: Action[]) => from(actions));

  constructor(private actions$: Actions,
              private zone: NgZone,
              private store: Store<State>) {
  }

  public handleRemove(snapshot, replay) {
    this.zone.run(() => replay.next([new eventActions.RemoveAction(snapshot.key)]));
  }

  public handleValue(snapshot, replay) {
    const val = snapshot.val() || {};

    console.log('snapshot', snapshot);

    Object.keys(val)
      .map((key) => console.log(val[key]));

    const events = Object.keys(val)
      .map((key) => Object.assign(val[key], {id: key}));

    const eventsActions = events.map((event) => new eventActions.LoadAction(event));

    this.zone.run(() =>
      replay.next(eventsActions as Action[])
    );

  }

}<commit_msg>comments<commit_after>import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/skip';
import 'rxjs/add/operator/takeUntil';
import { Injectable, NgZone } from '@angular/core';
import { Effect, Actions, toPayload } from '@ngrx/effects';
import { Action, Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { from } from 'rxjs/observable/from';
import * as firebase from 'firebase';
import * as eventActions from './events.actions';
import { Event } from './events.model';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { getEventsState, State } from '../../app.reducers';
import { getEntities } from './events.reducer';
import { SetCenterAction } from '../map/map.actions';

const database = firebase.database();

const eventsRef = database.ref('events');

// clearAndRandomiseEvents();

function clearAndRandomiseEvents() {
  let clearUpdates = {};
  clearUpdates['/events'] = {};
  firebase.database().ref().update(clearUpdates)
    .then(() => {
      let updates = {};

      for (let i = 0; i < 20; i++) {
        let newEventKey = eventsRef.push().key;
        updates['/events/' + newEventKey] = <Event> {
          id: null,
          title: newEventKey,
          location: {
            description: null,
            coords: {
              lat: getRandom(-36, -44),
              lng: getRandom(170, 182),
            },
            bounds: null,
            place_id: null,
          },
          imageUrl: 'https://unsplash.it/400/300/?random&asdf=' + Math.random(),
          description: `
          Lorem Ipsum is simply dummy text of the printing and typesetting industry. 
          Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, 
          when an unknown printer took a galley of type and scrambled it to make a type specimen book. 
          It has survived not only five centuries, but also the leap into electronic typesetting,
          remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset 
          sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like
          Aldus PageMaker including versions of Lorem Ipsum.`
        };
      }
      firebase.database().ref().update(updates);
    });

  function getRandom(min, max) {
    return Math.random() * (max - min) + min;
  }
}

/**
 * Effects offer a way to isolate and easily test side-effects within your
 * application.
 * The `toPayload` helper function returns just
 * the payload of the currently dispatched action, useful in
 * instances where the current state is not necessary.
 *
 * Documentation on `toPayload` can be found here:
 * https://github.com/ngrx/effects/blob/master/docs/api.md#topayload
 *
 * If you are unfamiliar with the operators being used in these examples, please
 * check out the sources below:
 *
 * Official Docs: http://reactivex.io/rxjs/manual/overview.html#categories-of-operators
 * RxJS 5 Operators By Example: https://gist.github.com/btroncone/d6cf141d6f2c00dc6b35
 */
@Injectable()
export class EventsEffects {

  @Effect()
  select$: Observable<Action> = this.actions$
    .ofType(eventActions.SELECT)
    .map(toPayload)
    .switchMap((id) =>
      this.store.select(getEventsState)
        .map(getEntities)
        .map((entities) => entities[id])
        .first()
    )
    .filter((event) => event && !!event.location)
    .map((event) => new SetCenterAction(event.location));

  @Effect()
  init$: Observable<Action> = this.actions$
    .ofType(eventActions.INIT)
    .map(toPayload)
    .startWith(null)
    .first()
    .switchMap(() => {
      let replay: ReplaySubject<Action[]> = new ReplaySubject();

      // TODO listen to child events once loaded
      eventsRef.on('value', (snapshot) => this.handleValue(snapshot, replay));
      eventsRef.on('child_removed', (snapshot) => this.handleRemove(snapshot, replay));

      return replay;
    })
    .mergeMap((actions: Action[]) => from(actions));

  constructor(private actions$: Actions,
              private zone: NgZone,
              private store: Store<State>) {
  }

  public handleRemove(snapshot, replay) {
    this.zone.run(() => replay.next([new eventActions.RemoveAction(snapshot.key)]));
  }

  public handleValue(snapshot, replay) {
    const val = snapshot.val() || {};

    Object.keys(val)
      .map((key) => console.log(val[key]));

    const events = Object.keys(val)
      .map((key) => Object.assign(val[key], {id: key}));

    const eventsActions = events.map((event) => new eventActions.LoadAction(event));

    this.zone.run(() =>
      replay.next(eventsActions as Action[])
    );

  }

}
{'fraction_non_alphanumeric': 0.1338101160862355, 'fraction_numerical': 0.00808457711442786, 'mean_word_length': 3.069590889919865, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 41, 'https://': 6, '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': '3820529', 'n_tokens_mistral': 2928, 'n_tokens_neox': 2806, 'n_words': 774}