Skip to content

Instantly share code, notes, and snippets.

@jurStv
Forked from peterbsmyth/recipe.example.md
Created April 26, 2018 08:27
Show Gist options
  • Save jurStv/2d13e970fbb0fbdec9d8e118dbcc817a to your computer and use it in GitHub Desktop.
Save jurStv/2d13e970fbb0fbdec9d8e118dbcc817a to your computer and use it in GitHub Desktop.

Revisions

  1. @peterbsmyth peterbsmyth revised this gist Mar 13, 2018. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion recipe.example.md
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,6 @@ import { Injectable } from '@angular/core';
    import { Effect, Actions } from '@ngrx/effects';
    import { Action } from '@ngrx/store';
    import { Observable } from 'rxjs/Observable';
    import { Scheduler } from 'rxjs/Scheduler';
    import { of } from 'rxjs/observable/of';
    import { handleError } from './handleError';

  2. @peterbsmyth peterbsmyth revised this gist Jan 7, 2018. No changes.
  3. @peterbsmyth peterbsmyth revised this gist Jan 7, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion recipe.example.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    ### Passing Data down an effects chain for multiple API Calls using Observable.ForkJoin
    ### Making chained API Calls using @ngrx/Effects
    #### Purpose
    This recipe is useful for cooking up chained API calls as a result of a single action.

  4. @peterbsmyth peterbsmyth created this gist Jan 7, 2018.
    79 changes: 79 additions & 0 deletions recipe.example.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    ### Passing Data down an effects chain for multiple API Calls using Observable.ForkJoin
    #### Purpose
    This recipe is useful for cooking up chained API calls as a result of a single action.

    #### Description
    In the below example, a single action called `POST_REPO` is dispatched and it's intention is to create a new repostiory on GitHub then update the README with new data after it is created.
    For this to happen there are 4 API calls necessary to the GitHub API:
    1. POST a new repostiry
    2. GET the master branch of the new repository
    3. GET the files on the master branch
    4. PUT the `README.md` file

    The `POST_REPO`'s payload contains `payload.repo` with information needed for API call 1.
    The response from API call 1 is necessary for API call 2.
    The response from API call 2 is necessary for API call 3.
    The response from API call 3 and `payload.file`, which has information needed to update the README.md file, is neccessary for API call 4.

    Using `Observable.ForkJoin` makes this possible.

    #### Example
    ```ts
    import { Injectable } from '@angular/core';
    import { Effect, Actions } from '@ngrx/effects';
    import { Action } from '@ngrx/store';
    import { Observable } from 'rxjs/Observable';
    import { Scheduler } from 'rxjs/Scheduler';
    import { of } from 'rxjs/observable/of';
    import { handleError } from './handleError';


    import { GithubService } from '../services/github.service';
    import * as githubActions from '../actions/github';

    @Injectable()
    export class GitHubEffects {
    @Effect()
    postRepo$: Observable<Action> = this.actions$
    .ofType(githubActions.POST_REPO)
    .map((action: githubActions.PostRepo) => action.payload)
    // return the payload and POST the repo
    .switchMap((payload: any) => Observable.forkJoin([
    Observable.of(payload),
    this.githubService.postRepo(payload.repo)
    ]))
    // return the repo and the master branch as an array
    .switchMap((data: any) => {
    const [payload, repo] = data;
    return Observable.forkJoin([
    Observable.of(payload),
    Observable.of(repo),
    this.githubService.getMasterBranch(repo.name)
    ]);
    })
    // return the payload, the repo, and get the sha for README
    .switchMap((data: any) => {
    const [payload, repo, branch] = data;
    return Observable.forkJoin([
    Observable.of(payload),
    Observable.of(repo),
    this.githubService.getFiles(repo.name, branch)
    .map((files: any) => files.tree
    .filter(file => file.path === 'README.md')
    .map(file => file.sha)[0]
    )
    ]);
    })
    // update README with data from payload.file
    .switchMap((data: any) => {
    const [payload, repo, sha] = data;
    payload.file.sha = sha;
    return this.githubService.putFile(repo.name, payload.file);
    });

    constructor(
    private actions$: Actions,
    private githubService: GithubService,
    ) {}
    }
    ```