Skip to content

Instantly share code, notes, and snippets.

@aruizeac
Forked from btroncone/ngrxintro.md
Created July 26, 2020 18:12
Show Gist options
  • Save aruizeac/b18737733242eb6bcc0fe64c60803772 to your computer and use it in GitHub Desktop.
Save aruizeac/b18737733242eb6bcc0fe64c60803772 to your computer and use it in GitHub Desktop.

Revisions

  1. @btroncone btroncone revised this gist Apr 3, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/

    *Update: Non-middleware examples have been updated to ngrx/store v2. More coming soon!*

    <a href="https://ultimatecourses.com/courses/rxjs?ref=4"><img src="https://ultimatecourses.com/static/banners/ultimate-angular-github.svg"></a>
    <a href="https://ultimatecourses.com/courses/angular?ref=4"><img src="https://ultimatecourses.com/static/banners/ultimate-angular-github.svg"></a>

    Table of Contents
    =================
  2. @btroncone btroncone revised this gist Apr 3, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/

    *Update: Non-middleware examples have been updated to ngrx/store v2. More coming soon!*

    <a href="https://ultimatecourses.com/courses/rxjs?ref=4"><img src="https://drive.google.com/uc?export=view&id=1htrban3k3Z8CxiKwEV6bdmxW5Wu8xdWX"></a>
    <a href="https://ultimatecourses.com/courses/rxjs?ref=4"><img src="https://ultimatecourses.com/static/banners/ultimate-angular-github.svg"></a>

    Table of Contents
    =================
  3. @btroncone btroncone revised this gist Apr 3, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/

    *Update: Non-middleware examples have been updated to ngrx/store v2. More coming soon!*

    <a href="https://ultimateangular.com/?ref=76683_kee7y7vk"><img src="https://ultimateangular.com/assets/img/banners/ua-github.svg"></a>
    <a href="https://ultimatecourses.com/courses/rxjs?ref=4"><img src="https://drive.google.com/uc?export=view&id=1htrban3k3Z8CxiKwEV6bdmxW5Wu8xdWX"></a>

    Table of Contents
    =================
  4. @btroncone btroncone revised this gist Feb 8, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -232,7 +232,7 @@ const subscriberTwo = mySubject.subscribe(val => {
    mySubject.next('FIRST VALUE!'); '***SUBSCRIBER ONE*** FIRST VALUE! ***SUBSCRIBER TWO*** FIRST VALUE!'
    mySubject.next('SECOND VALUE!'); '***SUBSCRIBER ONE*** SECOND VALUE! ***SUBSCRIBER TWO*** SECOND VALUE!'
    ```
    In Store (and Redux), it is convention to `dispatch` actions to the application store. To maintain this API, the `Dispatcher` extends Subject, adding a `dispatch` method as a passthrough to the classic `next` method. This is used to pass values into the Subject before emitting these values to subcribers.
    In Store (and Redux), it is convention to `dispatch` actions to the application store. To maintain this API, the `Dispatcher` extends Subject, adding a `dispatch` method as a passthrough to the classic `next` method. This is used to pass values into the Subject before emitting these values to subscribers.

    ###### Extending Subject as Dispatcher
    ```ts
  5. @btroncone btroncone revised this gist Feb 15, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@ Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/

    *Update: Non-middleware examples have been updated to ngrx/store v2. More coming soon!*

    <a href="https://ultimateangular.com/?ref=76683_kee7y7vk"><img src="https://ultimateangular.com/assets/img/banners/ua-github.svg"></a>

    Table of Contents
    =================
  6. @btroncone btroncone revised this gist Nov 29, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -578,7 +578,7 @@ While most operators are passed emitted values from the observable, `let` is han
    ###### Basic functionality of let
    ```ts
    const myArray = [1,2,3,4,5];
    const myObservableArray = Rx.Observable.fromArray(myArray);
    const myObservableArray = Rx.Observable.from(myArray);

    const test = myObservableArray
    .map(val => val + 1)
    @@ -717,7 +717,7 @@ Each view in our application generally is concerned with their own particular sl
    ```ts
    //only output distinct values, based on the last emitted value
    const myArrayWithDuplicatesInARow = new Rx.Observable
    .fromArray([1,1,2,2,3,1,2,3]);
    .from([1,1,2,2,3,1,2,3]);

    const distinctSub = myArrayWithDuplicatesInARow
    .distinctUntilChanged()
    @@ -730,7 +730,7 @@ const nonDistinctSub = myArrayWithDuplicatesInARow

    const sampleObject = {name: 'Test'};

    const myArrayWithDuplicateObjects = new Rx.Observable.fromArray([sampleObject, sampleObject, sampleObject]);
    const myArrayWithDuplicateObjects = new Rx.Observable.from([sampleObject, sampleObject, sampleObject]);
    //only out distinct objects, based on last emitted value
    const nonDistinctObjects = myArrayWithDuplicateObjects
    .distinctUntilChanged()
  7. @btroncone btroncone revised this gist Aug 24, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -437,7 +437,7 @@ const personInfo = [{name: 'Joe'}, {age: 31}, {birthday: '1/1/1985'}];
    /*
    1.) accumulator: {name: 'Joe'}, current: {age: 31}
    2.) accumulator: {name: 'Joe', age: 31}, current: {birthday: '1/1/1985'}
    Final: {name: 'Joe', age: 31, {birthday: '1'/1/1985'}}
    Final: {name: 'Joe', age: 31, birthday: '1'/1/1985'}
    */
    const fullPerson = personInfo.reduce((accumulator, current) => {
    return Object.assign({}, accumulator, current)
  8. @btroncone btroncone revised this gist Jul 19, 2017. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -213,7 +213,7 @@ The two pillars of @ngrx/store, the **store** and **dispatcher**, both extend Rx

    Because Subjects are Observers, you can *'next'*, or pass values into the stream directly. Subscribers of that Subject will then be notified of emitted values. In the context of Store, these subscribers could be a Angular 2 service, component, or anything requiring access to application state.

    ######Subscribing to a Subject
    ###### Subscribing to a Subject
    ```ts
    //create a subject
    const mySubject = new Rx.Subject();
    @@ -418,7 +418,7 @@ Reducers are the foundation of any Store or Redux-based application, describing

    Before we discuss how reducers are created and implemented, let's first look at the `reduce` function. Reduce takes an array of values, running a function against an accumulated value and current value, *reducing* your array into a single value upon completion. You can think of the accumulator as a snowball rolling downhill, gaining mass with each revolution. In the same way, the reduce accumulator is the result of applying your defined function to the current value through iteration.

    ######Standard Reduce
    ###### Standard Reduce
    ```ts
    /*
    You can think of reduce as a snowball rolling downhill. Each rotation (or iteration) mass is accumulated until we reach the bottom. Similarly with reduce, the returned value is passed to the next invocation of the supplied function until all values in the source array are exhausted. Let's see some examples to solidify this concept.
    @@ -618,7 +618,7 @@ const letTestFour = obsArrayPlusYourOperators(addTenThenTwenty)

    The `let` operator is a perfect fit for *@ngrx/store* middleware as an entry point is required for the user to add custom functionality *before* or *after* reducers output state. This is the basis for how pre and post middleware is applied in @ngrx/store.

    ######Adding let for a Middleware Entry Point
    ###### Adding let for a Middleware Entry Point
    ```ts
    class Store extends Rx.BehaviorSubject{
    constructor(
    @@ -666,7 +666,7 @@ This is the gist of the inner workings of store.

    The cornerstone function for projecting data from a collection is map. Map applies a specified function to each item, returning a new representation of that item. Because application state is a key/value object map of sections of state, it's simple to provide a helper function to return the requested slice of state based on a string, or any other relevant selector.

    ######Providing Slices of State with map
    ###### Providing Slices of State with map
    ```ts
    class Dispatcher extends Rx.Subject{
    dispatch(value : any) : void {
    @@ -1450,7 +1450,7 @@ export class App {
    _store.select('partyFilter'),
    (people, filter) => {
    return {
    total: people.length
    total: people.length,
    people: people.filter(filter),
    attending: people.filter(person => person.attending).length,
    guests: people.reduce((acc, curr) => acc + curr.guests, 0)
    @@ -1523,7 +1523,7 @@ export class App {
    and output statistics.
    */
    this.model = Observable.combineLatest(
    _store.select('people')
    _store.select('people'),
    _store.select('partyFilter')
    )
    //extracting party model to selector
  9. @btroncone btroncone revised this gist Jun 5, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1481,7 +1481,7 @@ export const partyModel = () => {
    attending: people.filter(person => person.attending).length,
    guests: people.reduce((acc, curr) => acc + curr.guests, 0)
    }
    })
    });
    };
    ```
  10. @btroncone btroncone revised this gist Jun 5, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1476,7 +1476,7 @@ export const partyModel = () => {
    return state => state
    .map(([people, filter]) => {
    return {
    total: people.length
    total: people.length,
    people: people.filter(filter),
    attending: people.filter(person => person.attending).length,
    guests: people.reduce((acc, curr) => acc + curr.guests, 0)
  11. @btroncone btroncone revised this gist May 8, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1324,7 +1324,7 @@ While building out your @ngrx/store application, many of your components will re
    The `combineLatest` operator accepts an unspecified number of observables, emitting the last emitted value from each when any of the provided observables emit. These values are passed to a projection function for you to form the appropriate projection.
    ######combineLatest Example
    ###### combineLatest Example
    ([demo](http://jsbin.com/lumaqanoha/1/edit?js,console))
    @@ -1379,7 +1379,7 @@ const subscribe = combinedProject.subscribe(latestValuesProject => console.log(l
    The `withLatestFrom` operator is similar, except it only combines the last emitted values from the provided observables when the source observable emits. This is useful when your projection depends first on a single source, aided by multiple other sources.
    ######withLatestFrom Example
    ###### withLatestFrom Example
    ([demo](http://jsbin.com/qicuzovepo/edit?js,console))
    @@ -1509,7 +1509,7 @@ export const percentAttending = () => {
    Applying selectors is easy, simply apply the `let` operator to the appropriate Observable, supplying the selector(s) of your choosing.
    ######Applying Selectors In Container Component
    ###### Applying Selectors In Container Component
    ```ts
    export class App {
    public model;
  12. @btroncone btroncone revised this gist May 8, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    #Comprehensive Introduction to @ngrx/store
    # Comprehensive Introduction to @ngrx/store
    By: [@BTroncone](https://twitter.com/btroncone)

    Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/angular-2-ngrx-store-in-10-minutes) on [egghead.io](https://www.egghead.io)!
  13. @btroncone btroncone revised this gist Oct 11, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -325,11 +325,11 @@ const storeSubscriberTwo = store.subscribe(val => {
    });

    //For demonstration, manually publish values to store
    myFirstStore.next('FIRST STORE VALUE!');
    store.next('FIRST STORE VALUE!');

    //Add another subscriber after 'FIRST VALUE!' published
    //output: ***STORE SUBSCRIBER THREE*** FIRST STORE VALUE!
    const subscriberThree = myFirstStore.subscribe(val => {
    const subscriberThree = store.subscribe(val => {
    console.log('***STORE SUBSCRIBER THREE***', val);
    });
    ```
  14. @btroncone btroncone revised this gist Jul 27, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1742,4 +1742,4 @@ Excellent RxJS and Redux related [Egghead.io](https://www.egghead.io) videos and
    * [Asynchronous Programming - The End of the Loop](https://egghead.io/series/mastering-asynchronous-programming-the-end-of-the-loop) - Jafar Husain
    * [Using the Async Pipe in Angular 2](https://egghead.io/lessons/angular-2-using-the-async-pipe-in-angular-2) - Brian Troncone
    **For clear examples, explanations, and resources for RxJS check out my new site at [http://learnrxjs.io/](http://learnrxjs.io/)!**
    **For additional examples, explanations, and resources for RxJS check out my new site at [http://learnrxjs.io/](http://learnrxjs.io/)!**
  15. @btroncone btroncone revised this gist Jul 27, 2016. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1740,3 +1740,6 @@ Excellent RxJS and Redux related [Egghead.io](https://www.egghead.io) videos and
    * [Introduction to Reactive Programming](https://egghead.io/series/introduction-to-reactive-programming) - André Staltz
    * [Getting Started With Redux](https://egghead.io/series/getting-started-with-redux) - Dan Abramov
    * [Asynchronous Programming - The End of the Loop](https://egghead.io/series/mastering-asynchronous-programming-the-end-of-the-loop) - Jafar Husain
    * [Using the Async Pipe in Angular 2](https://egghead.io/lessons/angular-2-using-the-async-pipe-in-angular-2) - Brian Troncone
    **For clear examples, explanations, and resources for RxJS check out my new site at [http://learnrxjs.io/](http://learnrxjs.io/)!**
  16. @btroncone btroncone revised this gist Jul 27, 2016. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1034,10 +1034,9 @@ export class PersonInput {
    ([Work Along](https://plnkr.co/edit/fiwsfPmb0mqnHCSTGdIY?p=preview) | [Completed Lesson](https://plnkr.co/edit/07HfvgkoNejiC8joyHNL?p=preview))
    The `AsyncPipe` is a unique, stateful pipe in Angular 2 meant for handling both Observables and Promises. When using the `AsyncPipe` in a template expression with Observables, the supplied Observable is subscribed to, with emitted values being displayed within your view. This pipe also handles unsubscribing to the supplied observable, saving you the mental overhead of manually cleaning up subscriptions in `ngOnDestroy`. In a Store application, you will find yourself leaning on the `AsyncPipe` heavily in nearly all of your component views. For a more detailed explanation of exactly how the `AsyncPipe` works, check out my article [*Understand and Utilize the AsyncPipe in Angular 2*](http://briantroncone.com/?p=623).
    The `AsyncPipe` is a unique, stateful pipe in Angular 2 meant for handling both Observables and Promises. When using the `AsyncPipe` in a template expression with Observables, the supplied Observable is subscribed to, with emitted values being displayed within your view. This pipe also handles unsubscribing to the supplied observable, saving you the mental overhead of manually cleaning up subscriptions in `ngOnDestroy`. In a Store application, you will find yourself leaning on the `AsyncPipe` heavily in nearly all of your component views. For a more detailed explanation of exactly how the `AsyncPipe` works, check out my article [*Understand and Utilize the AsyncPipe in Angular 2*](http://briantroncone.com/?p=623) or free [egghead.io](https://www.egghead.io) video [Using the Async Pipe in Angular 2](https://egghead.io/lessons/angular-2-using-the-async-pipe-in-angular-2).
    Utilizing the `AsyncPipe` in our templates is easy. Once included in the `pipes` property of the `@Component` decorator
    you can pipe any Observable (or promise) through `async` and a subscription will be created, updating the template value on source emission. Because we are using the `AsyncPipe`, we can also remove the manual subscription from the component constructor and `unsubscribe` from the `ngOnDestroy` lifecycle hook. This is now handled for us behind the scenes.
    Utilizing the `AsyncPipe` in our templates is easy. You can pipe any Observable (or promise) through `async` and a subscription will be created, updating the template value on source emission. Because we are using the `AsyncPipe`, we can also remove the manual subscription from the component constructor and `unsubscribe` from the `ngOnDestroy` lifecycle hook. This is now handled for us behind the scenes.
    ###### Refactoring to Async Pipe
    ```ts
  17. @btroncone btroncone revised this gist Jun 10, 2016. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -127,7 +127,7 @@ Store promotes the idea of <sup>7</sup> one-way data flow and explicitly dispatc
    ###### <sup>6</sup> Two-Way Data Binding
    ![counter two-way](http://imgur.com/JUimvDf.png)
    ###### <sup>7</sup> One Way Data-Flow
    ![counter one-way](http://imgur.com/aAA74lS.png)
    ![counter one-way](http://imgur.com/C6J4cac.png)
    ###### Non-Store Counter Example
    ([demo](https://gist.run/?id=f03ca24d7288835107f5b32f0274b44c))
    ```ts
    @@ -165,7 +165,6 @@ export class Counter{
    <h3>{{counter$ | async}}</h3>
    </div>
    `,
    pipes: [AsyncPipe],
    changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class Counter{
  18. @btroncone btroncone revised this gist Jun 10, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -93,7 +93,7 @@ export interface Action {
    }
    ```
    ###### <sup>5</sup> Dispatched Action Pipeline
    ![dispatch pipeline](http://imgur.com/Dho0sLV.png)
    ![dispatch pipeline](http://imgur.com/Z8b9k6U.png)
    ###### Sample Actions
    ```ts
    //simple action without a payload
  19. @btroncone btroncone revised this gist Jun 6, 2016. 1 changed file with 8 additions and 14 deletions.
    22 changes: 8 additions & 14 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -983,7 +983,7 @@ export class App {
    template: `
    <ul>
    <li
    *ngFor="#person of people"
    *ngFor="let person of people"
    [class.attending]="person.attending"
    >
    {{person.name}} - Guests: {{person.guests}}
    @@ -1059,8 +1059,7 @@ you can pipe any Observable (or promise) through `async` and a subscription will
    >
    </person-list>
    `,
    directives: [PersonList, PersonInput],
    pipes: [AsyncPipe]
    directives: [PersonList, PersonInput]
    })
    export class App {
    public people;
    @@ -1118,7 +1117,7 @@ To utilize `OnPush` change detection in our components, we need to set the `chan
    template: `
    <ul>
    <li
    *ngFor="#person of people"
    *ngFor="let person of people"
    [class.attending]="person.attending"
    >
    {{person.name}} - Guests: {{person.guests}}
    @@ -1202,7 +1201,7 @@ import {
    template: `
    <div class="margin-bottom-10">
    <select #selectList (change)="updateFilter.emit(selectList.value)">
    <option *ngFor="#filter of filters" value="{{filter.action}}">
    <option *ngFor="let filter of filters" value="{{filter.action}}">
    {{filter.friendly}}
    </option>
    </select>
    @@ -1259,8 +1258,7 @@ In this example, we are going to slice our state into multiple `Observables`, re
    >
    </person-list>
    `,
    directives: [PersonList, PersonInput, FilterSelect, PartyStats],
    pipes: [AsyncPipe]
    directives: [PersonList, PersonInput, FilterSelect, PartyStats]
    })
    export class App {
    public people;
    @@ -1294,7 +1292,7 @@ Now that we have all the necessary data, we can pass it down to our "dumb" compo
    template: `
    <ul>
    <li
    *ngFor="#person of people.filter(filter)"
    *ngFor="let person of people.filter(filter)"
    [class.attending]="person.attending"
    >
    {{person.name}} - Guests: {{person.guests}}
    @@ -1436,8 +1434,7 @@ Now that we have an understanding of these *combination* operators, we can clean
    >
    </person-list>
    `,
    directives: [PersonList, PersonInput, FilterSelect, PartyStats],
    pipes: [AsyncPipe]
    directives: [PersonList, PersonInput, FilterSelect, PartyStats]
    })
    export class App {
    public model;
    @@ -1693,11 +1690,8 @@ export const reset = reducer => {
    ###### Wrap Reducer On Bootstrap
    ```ts
    bootstrap(App, [
    LocalStorageService,
    //wrap people in reset meta-reducer
    provideStore({people: reset(people), partyFilter}),
    usePreMiddleware(actionLogger),
    usePostMiddleware(stateLogger, localStorageMiddleware('people'))
    provideStore({people: reset(people), partyFilter})
    ]);
    ```
  20. @btroncone btroncone revised this gist Jun 6, 2016. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -3,9 +3,7 @@ By: [@BTroncone](https://twitter.com/btroncone)

    Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/angular-2-ngrx-store-in-10-minutes) on [egghead.io](https://www.egghead.io)!

    *Note: I am in the process of updating for ngrx/store v2. The majority of concepts and functionality still apply, sans middleware.*

    *Update: Non-middleware examples have been updated to ngrx/store v2, more to come.*
    *Update: Non-middleware examples have been updated to ngrx/store v2. More coming soon!*


    Table of Contents
  21. @btroncone btroncone revised this gist Jun 6, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,8 @@ Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/

    *Note: I am in the process of updating for ngrx/store v2. The majority of concepts and functionality still apply, sans middleware.*

    *Update: Non-middleware examples have been updated to ngrx/store v2, more to come.*


    Table of Contents
    =================
  22. @btroncone btroncone revised this gist Jun 6, 2016. 1 changed file with 0 additions and 7 deletions.
    7 changes: 0 additions & 7 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -887,13 +887,6 @@ For the case of our starter application we will export a string constant for eac

    ###### Initial Actions
    ```ts
    /*
    I prefer to keep all action constants in one file,
    this provides a one stop reference for all relevant user interaction
    within your application. It also allows those new to project to see
    everything your app 'does' in a quick glance.
    */

    //Person Action Constants
    export const ADD_PERSON = 'ADD_PERSON';
    export const REMOVE_PERSON = 'REMOVE_PERSON';
  23. @btroncone btroncone revised this gist Jun 6, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -881,9 +881,9 @@ export const people = (state = [], action) => {

    ([Work Along](https://plnkr.co/edit/ceA9BhPE6LYLtiwEgDMC) | [Completed Lesson](https://plnkr.co/edit/fRGN46atIlmjqoyV4G36))

    The only way to modify state within a store application is by dispatching actions. Because of this, a log of actions should present a clear, readable, history of user interaction. Since actions are generally defined as string constants, aggregating these constants into a single file can also provide a one-stop dictionary, or reference for all relevant activity in your action. This can not only provide valuable insight into your applications intent, but also make it much easier to identify and recreate errors and bugs.
    The only way to modify state within a store application is by dispatching actions. Because of this, a log of actions should present a clear, readable, history of user interaction. Actions are generally defined as string constants or as static string values on services encapsulating a particular action type. In the latter case, functions are provided to return an appropriate action given the correct input. These methods, which help standardize your actions while providing additional type safety, are known as *action creators*.

    The creation of action constants is as easy as it sounds, simply export a string constant for each action within your application. These will then be used as the keys to your reducer case statements and the `type` for every dispatched action.
    For the case of our starter application we will export a string constant for each application action. These will then be used as the keys to our reducer case statements and the `type` for every dispatched action.

    ###### Initial Actions
    ```ts
  24. @btroncone btroncone revised this gist May 26, 2016. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -572,6 +572,8 @@ case, state) will continue to collect until destroyed. This makes it the ideal o

    ([let demo](http://jsbin.com/pizahoqese/edit?js,console) | [store demo](http://jsbin.com/jamukoyovo/edit?js,console))

    *Middleware has been removed in ngrx/store v2. It is still worth reading through this section to understand `let` as it can be used with selectors.*

    While most operators are passed emitted values from the observable, `let` is handed the *entire* observable. This allows the opportunity to tack on extra operators and functionality, before returning the source observable. While this may seem like a small nuance, it fits perfectly into situations like `middleware` or `selectors` (to be discussed later), where the consumer would like to define a composable, reusable block of code to be inserted at a particular slot in an observable chain.

    ###### Basic functionality of let
    @@ -1556,6 +1558,8 @@ interface Selector<T,V> {
    ([Work Along](https://plnkr.co/edit/LB3mId2knRUQTLlx4p9G?p=preview) | [Completed Lesson](https://plnkr.co/edit/tRAEE5XJcljrFnQbVg0p?p=preview))
    *Note: Middleware has been remove in ngrx/store v2. Please see the [meta-reducers](#implementing-a-meta-reducer) section for how to create similar functionality.*
    Middleware provides an easy-to-utilize entry point for inserting custom functionality into the action pipeline. Store middleware comes in two flavors, `preMiddleware` and `postMiddleware`, implemented using the RxJS `let` operator. Pre-middleware is applied before dispatched actions hit your reducers, passed an `Observable<Action>`. Post-middleware is invoked before the new representation of state is `next`ed into store, passed an `Observable<State>`
    The uses for middleware are many, from handling side-effect with sagas, to advanced logging of actions, to automatically syncing slices of state to local storage. In the Redux community, an entire ecosystem of custom middleware has been established. For our use, we'll be implementing simple logger middleware to keep track of dispatched actions and subsequent updates to state.
    @@ -1589,6 +1593,8 @@ bootstrap(App, [
    ([Work Along](https://plnkr.co/edit/tRAEE5XJcljrFnQbVg0p?p=preview) | [Completed Lesson](https://plnkr.co/edit/oBQ1rLfMV8MiPIzxW8t7?p=preview))
    *Note: Middleware has been remove in ngrx/store v2. Please see the [meta-reducers](#implementing-a-meta-reducer) section for how to create similar functionality.*
    When creating custom middleware you may find the need to utilize your Angular services. Store comes with a helper function, <sup>13</sup> `createMiddleware`, to make this process easy. The `createMiddleware` function takes a factory function, accepting any number of dependecies supplied as a second paramater. Behind the scenes, Store handles the Angular 2 provider setup, creating the proper tokens and injecting the declared Angular depencies into your middleware factory function. You can then utilize these dependencies as you wish to produce the desired result.
    In this example we are going to create a `LocalStorageService`, wrapping the local storage API for use in the party planner application. This service will then be injected into our custom `localStorageMiddleware`, which accepts a state key to keep in sync with local storage. All that is left to do is apply this as `postMiddleware` on application bootstrap and any state updates to the predefined section will be reflected in local storage.
    @@ -1628,6 +1634,8 @@ export const localStorageMiddleware = key => createMiddleware(localStorageServic
    ([Work Along](https://plnkr.co/edit/oBQ1rLfMV8MiPIzxW8t7?p=preview) | [Completed Lesson](https://plnkr.co/edit/4wFpmsCpDhGW6h1WopyC?p=preview))
    *Note: Middleware has been remove in ngrx/store v2. Please see the [meta-reducers](#implementing-a-meta-reducer) section for how to create similar functionality.*
    There are times when you will want to provide initial state to your reducers, outside of initial state supplied as a default function parameter. In these scenarios, store provides an `INITIAL_STATE` token which can be imported an overridden in order update state accordingly on application bootstrap. Behind the scenes, store will first check if the data has been initialized under the `INITIAL_STATE` token and if so, use this as the default initial state for the appropriate reducer.
    To demonstrate this, we will expand upon the previous example and rehydrate the state collected in local store when the application is close or the page is refreshed. To handle this, we expose a function that accepts a key to rehydrate, returning a Angular provider for `INITIAL_STATE`, returning our data from local storage as the value. Now, when store asks for `INITIAL_STATE`, Angular will return our rehydrated data.
  25. @btroncone btroncone revised this gist May 26, 2016. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@ By: [@BTroncone](https://twitter.com/btroncone)

    Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/angular-2-ngrx-store-in-10-minutes) on [egghead.io](https://www.egghead.io)!

    *Note: I am in the process of updating for ngrx/store v2. The majority of concepts and functionality still apply, sans middleware.*


    Table of Contents
    =================
  26. @btroncone btroncone revised this gist May 8, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1484,6 +1484,7 @@ export const partyModel = () => {
    return state => state
    .map(([people, filter]) => {
    return {
    total: people.length
    people: people.filter(filter),
    attending: people.filter(person => person.attending).length,
    guests: people.reduce((acc, curr) => acc + curr.guests, 0)
  27. @btroncone btroncone revised this gist May 8, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1416,7 +1416,7 @@ Now that we have an understanding of these *combination* operators, we can clean
    template: `
    <h3>@ngrx/store Party Planner</h3>
    <party-stats
    [invited]="(model | async)?.people.length"
    [invited]="(model | async)?.total"
    [attending]="(model | async)?.attending"
    [guests]="(model | async)?.guests"
    >
    @@ -1458,6 +1458,7 @@ export class App {
    _store.select('partyFilter'),
    (people, filter) => {
    return {
    total: people.length
    people: people.filter(filter),
    attending: people.filter(person => person.attending).length,
    guests: people.reduce((acc, curr) => acc + curr.guests, 0)
  28. @btroncone btroncone revised this gist Apr 30, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1169,7 +1169,7 @@ import {
    } from './actions';

    //return appropriate function depending on selected filter
    export const partyFilter = (state = 'SHOW_ATTENDING', action = person => person) => {
    export const partyFilter = (state = person => person, action) => {
    switch(action.type){
    case SHOW_ATTENDING:
    return person => person.attending;
  29. @btroncone btroncone revised this gist Apr 30, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #Comprehensive Introduction to @ngrx/store
    By: [@BTroncone](https://twitter.com/btroncone)

    Also check out [@ngrx/store in 10 minutes](https://egghead.io/lessons/angular-2-ngrx-store-in-10-minutes) on [egghead.io](https://www.egghead.io)!
    Also check out my lesson [@ngrx/store in 10 minutes](https://egghead.io/lessons/angular-2-ngrx-store-in-10-minutes) on [egghead.io](https://www.egghead.io)!


    Table of Contents
  30. @btroncone btroncone revised this gist Apr 30, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ngrxintro.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #Comprehensive Introduction to @ngrx/store
    By: [@BTroncone](https://twitter.com/btroncone)

    Written version of future [egghead.io](https://www.egghead.io) video series.
    Also check out [@ngrx/store in 10 minutes](https://egghead.io/lessons/angular-2-ngrx-store-in-10-minutes) on [egghead.io](https://www.egghead.io)!


    Table of Contents