Last active
November 6, 2017 18:14
-
-
Save peterbsmyth/8b569c54cb000f48727d8d4f59e25b19 to your computer and use it in GitHub Desktop.
Showing an architectural question
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { | |
repoName: any; | |
action: any; | |
@Effect() | |
postRepo$: Observable<Action> = this.actions$ | |
.ofType(githubActions.POST_REPO) | |
// store the action for later use | |
.do(action => this.action = action) | |
.map((action: githubActions.PostRepo) => action.payload.postRepo) | |
// add the repo | |
.switchMap((data) => this.githubService.postRepo(data)) | |
.do((repo: any) => this.repoName = repo.name) | |
// get the master branch | |
.switchMap((repo: any) => this.githubService.getMasterBranch(repo.name)) | |
// get the sha for README | |
.switchMap((repo: any) => this.githubService.getFiles(this.repoName, repo)) | |
.map((files: any) => files.tree | |
.filter(file => file.path === 'README.md') | |
.map(file => file.sha)[0]) | |
// update README with form input | |
.switchMap((sha) => { | |
this.action.payload.putFile.sha = sha; | |
return this.githubService.putFile(this.repoName, this.action.payload.putFile); | |
}) | |
.map((res) => new githubActions.PostRepoComplete(res)) | |
.catch(handleError); | |
constructor( | |
private actions$: Actions, | |
private githubService: GithubService, | |
) {} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable } from '@angular/core'; | |
import { HttpClient } from '@angular/common/http'; | |
import { Observable } from 'rxjs/Observable'; | |
import { environment } from '../../environments/environment'; | |
@Injectable() | |
export class GithubService { | |
constructor(private http: HttpClient) { } | |
postRepo(data): Observable<object> { | |
return this.http.post(`https://api.github.com/user/repos`, data); | |
} | |
putFile(repoName, data): Observable<object> { | |
return this.http.put(`https://api.github.com/repos/peterbsmith2/${repoName}/contents/${data.path}`, data); | |
} | |
postFile(data): Observable<object> { | |
return this.http.put(`https://api.github.com/repos/peterbsmith2/read-test/contents/chapter_01.md`, data); | |
} | |
getRepos(): Observable<object> { | |
return this.http.get(`https://api.github.com/user/repos?per_page=100&affiliation=owner`); | |
} | |
getFiles(name, repo): Observable<object> { | |
const tree = repo.commit.commit.tree.sha; | |
return this.http.get(`https://api.github.com/repos/peterbsmith2/${name}/git/trees/${tree}`); | |
} | |
getMasterBranch(repo): Observable<object> { | |
return this.http.get(`https://api.github.com/repos/peterbsmith2/${repo}/branches/master`); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core'; | |
import { Observable } from 'rxjs/Observable'; | |
import { Store } from '@ngrx/store'; | |
import * as fromRoot from '../../reducers'; | |
import * as app from '../../actions/app'; | |
import * as githubActions from '../../actions/github'; | |
import outdent from 'outdent'; | |
/** | |
* Class that acts as smart container for the SettingsFormComponent | |
*/ | |
@Component({ | |
selector: 'cms-settings', | |
templateUrl: './settings.component.html', | |
styleUrls: ['./settings.component.css'], | |
changeDetection: ChangeDetectionStrategy.OnPush, | |
}) | |
export class SettingsComponent implements OnInit { | |
/** | |
* Constructor injection and assigning the original name to name$ | |
* @param {Store<fromRoot.State>} store - Injection of store | |
*/ | |
constructor( | |
private store: Store<fromRoot.State>, | |
) { } | |
/** | |
* Dispatches a SetNameAction with the name on the submitted form as the payload | |
* @param form - Form object that is to be submitted | |
*/ | |
submit(form) { | |
let formatted; | |
if (form.chapters.length > 0) { | |
formatted = outdent` | |
# ${form.title} | |
## ${form.subtitle} | |
## ${form.author} | |
[Amazon](${form.amazonLink}) | [B&N](${form.bnLink}) | |
## Chapters | |
${form.chapters.map(chapter => `**${chapter.chapterNumber}.** ${chapter.chapterTitle} `).join('\n')} | |
`; | |
} else { | |
formatted = outdent` | |
# ${form.title} | |
## ${form.subtitle} | |
## ${form.author} | |
[Amazon](${form.amazonLink}) | [B&N](${form.bnLink}) | |
## Chapters | |
`; | |
} | |
const postRepo = { | |
name: `read-${form.title.toLowerCase().split(' ').join('-')}`, | |
description: `${form.title}`, | |
has_issues: false, | |
has_projects: false, | |
has_wiki: false, | |
auto_init: true, | |
allow_squash_merge: false, | |
allow_merge_commit: false, | |
}; | |
const putFile = { | |
path: 'README.md', | |
message: 'add README', | |
content: btoa(formatted), | |
sha: '', | |
committer: { | |
name: 'Peter B Smith', | |
email: 'peter@upstate.agency' | |
} | |
}; | |
this.store.dispatch(new githubActions.PostRepo({postRepo, putFile})); | |
} | |
/** | |
* Doesn't do anything | |
*/ | |
ngOnInit() { | |
} | |
} |
New Challenge
Desired outcome:
- call
this.githubService.postRepo(repo)
- call
this.githubService.getMasterBranch(repo.name)
- After
getMasterBranch
, use therepo
from 1. as well as thebranch
from 2. as inputs to `getFiles(repo, branch)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Intro
submit(form)
insettings.component.ts
dispatches an action with side effects that is handled ingithub.effects.ts
, which fires a chain of github API requests that are contained ingithub.service.ts
. The result is:submit(form)
.Most Important Immediate Question
On line 23 of
github.effects.ts
I use a.do
operator to save the action for re-use later on line 38. I'm convinced there is a better way to architect this.