diff --git a/.angular-cli.json b/.angular-cli.json
index fd1dc1a..1684599 100644
--- a/.angular-cli.json
+++ b/.angular-cli.json
@@ -1,60 +1,65 @@
{
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
- "project": {
- "name": "gen"
- },
- "apps": [
- {
- "root": "src",
- "outDir": "dist",
- "assets": [
- "assets",
- "favicon.ico"
- ],
- "index": "index.html",
- "main": "main.ts",
- "polyfills": "polyfills.ts",
- "test": "test.ts",
- "tsconfig": "tsconfig.app.json",
- "testTsconfig": "tsconfig.spec.json",
- "prefix": "app",
- "styles": [
- "styles.css"
- ],
- "scripts": [],
- "environmentSource": "environments/environment.ts",
- "environments": {
- "dev": "environments/environment.ts",
- "prod": "environments/environment.prod.ts"
- }
- }
- ],
- "e2e": {
- "protractor": {
- "config": "./protractor.conf.js"
- }
- },
- "lint": [
- {
- "project": "src/tsconfig.app.json",
- "exclude": "**/node_modules/**"
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "project": {
+ "name": "gen"
},
- {
- "project": "src/tsconfig.spec.json",
- "exclude": "**/node_modules/**"
+ "apps": [
+ {
+ "root": "src",
+ "outDir": "dist",
+ "assets": [
+ "assets",
+ "favicon.ico"
+ ],
+ "index": "index.html",
+ "main": "main.ts",
+ "polyfills": "polyfills.ts",
+ "test": "test.ts",
+ "tsconfig": "tsconfig.app.json",
+ "testTsconfig": "tsconfig.spec.json",
+ "prefix": "app",
+ "styles": [
+ "styles.css"
+ ],
+ "scripts": [],
+ "environmentSource": "environments/environment.ts",
+ "environments": {
+ "dev": "environments/environment.ts",
+ "prod": "environments/environment.prod.ts"
+ }
+ }
+ ],
+ "e2e": {
+ "protractor": {
+ "config": "./protractor.conf.js"
+ }
},
- {
- "project": "e2e/tsconfig.e2e.json",
- "exclude": "**/node_modules/**"
+ "lint": [
+ {
+ "project": "src/tsconfig.app.json",
+ "exclude": "**/node_modules/**"
+ },
+ {
+ "project": "src/tsconfig.spec.json",
+ "exclude": "**/node_modules/**"
+ },
+ {
+ "project": "e2e/tsconfig.e2e.json",
+ "exclude": "**/node_modules/**"
+ }
+ ],
+ "test": {
+ "karma": {
+ "config": "./karma.conf.js"
+ }
+ },
+ "defaults": {
+ "styleExt": "css",
+ "component": {},
+ "serve": {
+ "port": 4200,
+ "host": "0.0.0.0",
+ "public-host": "dev.bitchmints.com:4200"
+ }
}
- ],
- "test": {
- "karma": {
- "config": "./karma.conf.js"
- }
- },
- "defaults": {
- "styleExt": "css",
- "component": {}
- }
}
diff --git a/package.json b/package.json
index ea60fa4..c955bf1 100644
--- a/package.json
+++ b/package.json
@@ -1,49 +1,58 @@
{
- "name": "gen",
- "version": "0.0.0",
- "license": "MIT",
- "scripts": {
- "ng": "ng",
- "start": "ng serve",
- "build": "ng build",
- "test": "ng test",
- "lint": "ng lint",
- "e2e": "ng e2e"
- },
- "private": true,
- "dependencies": {
- "@angular/animations": "^4.2.4",
- "@angular/common": "^4.2.4",
- "@angular/compiler": "^4.2.4",
- "@angular/core": "^4.2.4",
- "@angular/forms": "^4.2.4",
- "@angular/http": "^4.2.4",
- "@angular/platform-browser": "^4.2.4",
- "@angular/platform-browser-dynamic": "^4.2.4",
- "@angular/router": "^4.2.4",
- "core-js": "^2.4.1",
- "rxjs": "^5.4.2",
- "zone.js": "^0.8.14"
- },
- "devDependencies": {
- "@angular/cli": "1.4.3",
- "@angular/compiler-cli": "^4.2.4",
- "@angular/language-service": "^4.2.4",
- "@types/jasmine": "~2.5.53",
- "@types/jasminewd2": "~2.0.2",
- "@types/node": "~6.0.60",
- "codelyzer": "~3.1.1",
- "jasmine-core": "~2.6.2",
- "jasmine-spec-reporter": "~4.1.0",
- "karma": "~1.7.0",
- "karma-chrome-launcher": "~2.1.1",
- "karma-cli": "~1.0.1",
- "karma-coverage-istanbul-reporter": "^1.2.1",
- "karma-jasmine": "~1.1.0",
- "karma-jasmine-html-reporter": "^0.2.2",
- "protractor": "~5.1.2",
- "ts-node": "~3.2.0",
- "tslint": "~5.3.2",
- "typescript": "~2.3.3"
- }
+ "name": "gen",
+ "version": "0.0.0",
+ "license": "MIT",
+ "scripts": {
+ "ng": "ng",
+ "start": "ng serve",
+ "build": "ng build",
+ "test": "ng test",
+ "lint": "ng lint",
+ "e2e": "ng e2e"
+ },
+ "ngrxGen": {
+ "basePath": "./src/app",
+ "seperateDirectory": "true"
+ },
+ "private": true,
+ "dependencies": {
+ "@angular/animations": "^4.2.4",
+ "@angular/common": "^4.2.4",
+ "@angular/compiler": "^4.2.4",
+ "@angular/core": "^4.2.4",
+ "@angular/forms": "^4.2.4",
+ "@angular/http": "^4.2.4",
+ "@angular/platform-browser": "^4.2.4",
+ "@angular/platform-browser-dynamic": "^4.2.4",
+ "@angular/router": "^4.2.4",
+ "@ngrx/effects": "^4.0.5",
+ "@ngrx/store": "^4.0.3",
+ "@ngrx/store-devtools": "^4.0.0",
+ "bootstrap": "^3.3.7",
+ "core-js": "^2.4.1",
+ "font-awesome": "^4.7.0",
+ "rxjs": "^5.4.2",
+ "zone.js": "^0.8.14"
+ },
+ "devDependencies": {
+ "@angular/cli": "1.4.3",
+ "@angular/compiler-cli": "^4.2.4",
+ "@angular/language-service": "^4.2.4",
+ "@types/jasmine": "~2.5.53",
+ "@types/jasminewd2": "~2.0.2",
+ "@types/node": "~6.0.60",
+ "codelyzer": "~3.1.1",
+ "jasmine-core": "~2.6.2",
+ "jasmine-spec-reporter": "~4.1.0",
+ "karma": "~1.7.0",
+ "karma-chrome-launcher": "~2.1.1",
+ "karma-cli": "~1.0.1",
+ "karma-coverage-istanbul-reporter": "^1.2.1",
+ "karma-jasmine": "~1.1.0",
+ "karma-jasmine-html-reporter": "^0.2.2",
+ "protractor": "~5.1.2",
+ "ts-node": "~3.2.0",
+ "tslint": "~5.3.2",
+ "typescript": "~2.3.3"
+ }
}
diff --git a/serve.sh b/serve.sh
new file mode 100755
index 0000000..d6d231d
--- /dev/null
+++ b/serve.sh
@@ -0,0 +1 @@
+clear && ng serve --public-host=dev.bitchmints.com:4200
diff --git a/src/app/actions/podcasts.actions.ts b/src/app/actions/podcasts.actions.ts
new file mode 100644
index 0000000..ff59909
--- /dev/null
+++ b/src/app/actions/podcasts.actions.ts
@@ -0,0 +1,26 @@
+import { Action } from '@ngrx/store';
+
+export const LOAD = '[Podcasts] Load';
+export const LOAD_SUCCESS = '[Podcasts] Load Success';
+export const LOAD_FAIL = '[Podcasts] Load Fail';
+
+export class LoadAction implements Action {
+ readonly type = LOAD;
+}
+
+export class LoadSuccessAction implements Action {
+ readonly type = LOAD_SUCCESS;
+
+ constructor(public payload: any) { }
+}
+
+export class LoadFailAction implements Action {
+ readonly type = LOAD_FAIL;
+
+ constructor(public payload: any) { }
+}
+
+export type Actions =
+ | LoadAction
+ | LoadSuccessAction
+ | LoadFailAction;
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 46d517b..d7782d8 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,20 +1,10 @@
- Welcome to {{title}}!
+ Hello, {{title}}!
-

+
-
Here are some links to help you start:
-
-
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
deleted file mode 100644
index bcbdf36..0000000
--- a/src/app/app.component.spec.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { TestBed, async } from '@angular/core/testing';
-import { AppComponent } from './app.component';
-describe('AppComponent', () => {
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- declarations: [
- AppComponent
- ],
- }).compileComponents();
- }));
- it('should create the app', async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.debugElement.componentInstance;
- expect(app).toBeTruthy();
- }));
- it(`should have as title 'app'`, async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.debugElement.componentInstance;
- expect(app.title).toEqual('app');
- }));
- it('should render title in a h1 tag', async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- fixture.detectChanges();
- const compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
- }));
-});
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 7b0f672..7ea7bf7 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,10 +1,22 @@
import { Component } from '@angular/core';
+import { Store } from '@ngrx/store';
+import { Observable } from 'rxjs/Observable';
+import { LoadAction } from 'app/actions/podcasts.actions';
+import { State } from 'app/reducers';
+
@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
})
export class AppComponent {
- title = 'app';
+ title = 'Sailor';
+ podcasts$: Observable
;
+
+ constructor(private store: Store){
+ console.log('AppComponent', 'ctor', store);
+ this.podcasts$ = this.store.select(p => p.podcasts.result);
+ this.store.dispatch(new LoadAction());
+ }
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index f657163..f7fddef 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,16 +1,31 @@
import { BrowserModule } from '@angular/platform-browser';
+import { HttpModule } from '@angular/http';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
+import { StoreModule } from '@ngrx/store';
+import { EffectsModule } from '@ngrx/effects';
+import { StoreDevtoolsModule } from '@ngrx/store-devtools';
+
+import { reducers } from './reducers';
+import { PodcastsEffects } from './effects/podcasts.effects';
+import { PodcastsService } from './services/podcasts.service';
+
@NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule
- ],
- providers: [],
- bootstrap: [AppComponent]
+ declarations: [
+ AppComponent
+ ],
+ imports: [
+ BrowserModule, HttpModule,
+
+ StoreModule.forRoot(reducers),
+ EffectsModule.forRoot([PodcastsEffects]),
+ StoreDevtoolsModule.instrument({maxAge: 25})
+ ],
+ providers: [
+ PodcastsService
+ ],
+ bootstrap: [AppComponent]
})
export class AppModule { }
diff --git a/src/app/effects/podcasts.effects.ts b/src/app/effects/podcasts.effects.ts
new file mode 100644
index 0000000..57f2410
--- /dev/null
+++ b/src/app/effects/podcasts.effects.ts
@@ -0,0 +1,26 @@
+import { Injectable } from '@angular/core';
+import { Actions, Effect } from '@ngrx/effects';
+import { Observable } from 'rxjs/Observable';
+import { PodcastsService } from '../services/podcasts.service';
+import * as podcasts from '../actions/podcasts.actions';
+import 'rxjs/add/operator/switchMap';
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/catch';
+import 'rxjs/add/observable/of';
+
+@Injectable()
+export class PodcastsEffects {
+ constructor(
+ private podcastsService: PodcastsService,
+ private actions$: Actions
+ ) { }
+
+ @Effect() get$ = this.actions$
+ .ofType(podcasts.LOAD)
+ .switchMap(payload => this.podcastsService.get()
+ // If successful, dispatch success action with result
+ .map(res => ({ type: podcasts.LOAD_SUCCESS, payload: res.json() }))
+ // If request fails, dispatch failed action
+ .catch(() => Observable.of({ type: podcasts.LOAD_FAIL}))
+ );
+}
diff --git a/src/app/reducers/index.ts b/src/app/reducers/index.ts
new file mode 100644
index 0000000..7c5c5c4
--- /dev/null
+++ b/src/app/reducers/index.ts
@@ -0,0 +1,10 @@
+import * as fromPodcasts from './podcasts.reducer';
+import { ActionReducerMap } from '@ngrx/store';
+
+export interface State {
+ podcasts: fromPodcasts.State;
+}
+
+export const reducers: ActionReducerMap = {
+ podcasts: fromPodcasts.reducer
+}
diff --git a/src/app/reducers/podcasts.reducer.ts b/src/app/reducers/podcasts.reducer.ts
new file mode 100644
index 0000000..abe2d9f
--- /dev/null
+++ b/src/app/reducers/podcasts.reducer.ts
@@ -0,0 +1,46 @@
+import * as podcasts from '../actions/podcasts.actions';
+
+export interface State {
+ loading: boolean;
+ entities: { [id: string]: any };
+ result: string[];
+}
+
+export const initialState: State = {
+ loading: false,
+ entities: {},
+ result: []
+}
+
+export function reducer(state = initialState, action: podcasts.Actions): State {
+ switch (action.type) {
+ case podcasts.LOAD: {
+ return {
+ ...state,
+ result: [],
+ loading: true
+ }
+ }
+
+ case podcasts.LOAD_SUCCESS: {
+
+ return {
+ ...state,
+ result: action.payload,
+ loading: false,
+ };
+ }
+
+ case podcasts.LOAD_FAIL: {
+
+ return {
+ ...state,
+ loading: false,
+ };
+ }
+
+ default: {
+ return state;
+ }
+ }
+}
diff --git a/src/app/services/podcasts.service.ts b/src/app/services/podcasts.service.ts
new file mode 100644
index 0000000..37d7dbf
--- /dev/null
+++ b/src/app/services/podcasts.service.ts
@@ -0,0 +1,13 @@
+import { Injectable } from '@angular/core';
+import { Http } from '@angular/http';
+import { Observable } from 'rxjs/Observable';
+
+@Injectable()
+export class PodcastsService {
+
+ constructor(private http: Http) { }
+ get() : Observable {
+ console.log('PodcastsService', 'get');
+ return this.http.get('https://jsonplaceholder.typicode.com/posts');
+ }
+}
diff --git a/src/styles.css b/src/styles.css
index 90d4ee0..40e7da6 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -1 +1,3 @@
/* You can add global styles to this file, and also import other style files */
+@import "~bootstrap/dist/css/bootstrap.min.css";
+@import "~font-awesome/css/font-awesome.css";
diff --git a/yarn.lock b/yarn.lock
index 83e3e19..9a0e4f9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -159,6 +159,18 @@
dependencies:
tsickle "^0.21.0"
+"@ngrx/effects@^4.0.5":
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-4.0.5.tgz#1224763800621b7305f9b18bc17ee09b25c861d1"
+
+"@ngrx/store-devtools@^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/@ngrx/store-devtools/-/store-devtools-4.0.0.tgz#b79c24773217df7fd9735ad21f9cbf2533c96e04"
+
+"@ngrx/store@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-4.0.3.tgz#36abacdfa19bfb8506e40de80bae06050a1e15e9"
+
"@ngtools/json-schema@1.1.0", "@ngtools/json-schema@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.1.0.tgz#c3a0c544d62392acc2813a42c8a0dc6f58f86922"
@@ -671,6 +683,10 @@ boom@5.x.x:
dependencies:
hoek "4.x.x"
+bootstrap@^3.3.7:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.3.7.tgz#5a389394549f23330875a3b150656574f8a9eb71"
+
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
@@ -1968,6 +1984,10 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
+font-awesome@^4.7.0:
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
+
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"