From 2c95d86be5aaa65bd0fbaf30ed896e5709e2bc2c Mon Sep 17 00:00:00 2001
From: Bruno Leonardo Michels
Date: Sun, 17 Jun 2018 18:57:00 -0300
Subject: [PATCH 1/6] Add redux packages and helpers
---
package-lock.json | 57 ++++++++++++++++++++++++++++++++++++++++++-----
package.json | 6 +++++
2 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 4b8b6aa..62ce5f3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -577,6 +577,24 @@
}
}
},
+ "@angular-redux/form": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/@angular-redux/form/-/form-9.0.1.tgz",
+ "integrity": "sha512-qcrpwW05vG3UrjMNZTHICkgA4oeUbfImqeGLwjUAGca1xsnS11eYecGIZ+BrbaaveUWsUJPL9lYaJOn90eesRQ==",
+ "requires": {
+ "immutable": "^3.8.1"
+ }
+ },
+ "@angular-redux/router": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@angular-redux/router/-/router-9.0.0.tgz",
+ "integrity": "sha512-8cfgoNMKZuTjLuEclzKpUURpSetQxo9tiuMWz8KnIFCFP6btvQHzYyDhfR2ROq+bwDpIXlUI6C4bWAORYD1DGw=="
+ },
+ "@angular-redux/store": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/@angular-redux/store/-/store-9.0.0.tgz",
+ "integrity": "sha512-0aWUktzTK88xDoDlGUDmDBnGW1ZB21W3H9dq0E52fuaN87cwtdca83ioi20/YT+M6EOecYPY7il9fSpy/Ewd1A=="
+ },
"@angular/animations": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-6.0.5.tgz",
@@ -5968,6 +5986,11 @@
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
"dev": true
},
+ "immutable": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+ "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
+ },
"import-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
@@ -6687,8 +6710,7 @@
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
- "dev": true
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
},
"js-yaml": {
"version": "3.7.0",
@@ -7681,7 +7703,6 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
"integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
- "dev": true,
"requires": {
"js-tokens": "^3.0.0"
}
@@ -8194,6 +8215,14 @@
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
+ "ngx-redux-state-props": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/ngx-redux-state-props/-/ngx-redux-state-props-0.0.2.tgz",
+ "integrity": "sha512-dI/ythdbhrrSdurJXWb/1l9gpBV4s00p+sQDUylmIm8JlMDgKGS/DTVvvU5H12wnZwA0dWMor5qdNvauGEh8rg==",
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
"ngx-take-until-destroy": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ngx-take-until-destroy/-/ngx-take-until-destroy-3.0.0.tgz",
@@ -9902,6 +9931,20 @@
"dev": true,
"optional": true
},
+ "redux": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.0.tgz",
+ "integrity": "sha512-NnnHF0h0WVE/hXyrB6OlX67LYRuaf/rJcbWvnHHEPCF/Xa/AZpwhs/20WyqzQae5x4SD2F9nPObgBh2rxAgLiA==",
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "symbol-observable": "^1.2.0"
+ }
+ },
+ "redux-thunk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
+ "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
+ },
"reflect-metadata": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz",
@@ -11337,6 +11380,11 @@
"has-flag": "^1.0.0"
}
},
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+ },
"tapable": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz",
@@ -11597,8 +11645,7 @@
"tslib": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz",
- "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==",
- "dev": true
+ "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw=="
},
"tslint": {
"version": "5.10.0",
diff --git a/package.json b/package.json
index c46b851..413bfc5 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,9 @@
},
"private": true,
"dependencies": {
+ "@angular-redux/form": "^9.0.1",
+ "@angular-redux/router": "^9.0.0",
+ "@angular-redux/store": "^9.0.0",
"@angular/animations": "^6.0.5",
"@angular/common": "^6.0.5",
"@angular/compiler": "^6.0.5",
@@ -26,7 +29,10 @@
"@angular/router": "^6.0.5",
"bootstrap": "^4.0.0-beta.2",
"core-js": "^2.4.1",
+ "ngx-redux-state-props": "0.0.2",
"ngx-take-until-destroy": "^3.0.0",
+ "redux": "^4.0.0",
+ "redux-thunk": "^2.3.0",
"rxjs": "^6.2.1",
"rxjs-compat": "^6.0.0-rc.0",
"zone.js": "^0.8.26"
From 6c9a7ab70e6e62120fe0dd84fb8ff4f8f62efa0b Mon Sep 17 00:00:00 2001
From: Bruno Leonardo Michels
Date: Sun, 17 Jun 2018 18:57:42 -0300
Subject: [PATCH 2/6] Configure reducers, store and initialize
---
src/app/app.component.ts | 33 +++++++++++++++++++++++++++++++++
src/app/app.module.ts | 12 +++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index a70f453..0ef9d42 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,4 +1,10 @@
+import { NgReduxRouter, routerReducer } from '@angular-redux/router';
+import { DevToolsExtension, NgRedux } from '@angular-redux/store';
import { Component } from '@angular/core';
+import { combineReducers } from 'redux';
+import thunk from 'redux-thunk';
+
+import { AboutReducer } from './about/services/about.reducer';
@Component({
selector: 'app-root',
@@ -7,4 +13,31 @@ import { Component } from '@angular/core';
})
export class AppComponent {
title = 'app';
+
+ constructor(
+ private ngRedux: NgRedux,
+ private ngReduxRouter: NgReduxRouter,
+ private devTools: DevToolsExtension,
+ ) {
+ const rootReducer = combineReducers({
+ about: this.createReducer(AboutReducer),
+ router: routerReducer,
+ });
+ this.ngRedux.configureStore(
+ rootReducer,
+ {},
+ [thunk],
+ this.devTools.isEnabled() ? [this.devTools.enhancer()] : undefined,
+ );
+ this.ngReduxRouter.initialize();
+ }
+
+ createReducer(ReducerService) {
+ const reducer = new ReducerService();
+ const defaultCallback = (s = {}) => s;
+
+ return (state = {}, action) => {
+ return (reducer[action.type] || defaultCallback)(state, action);
+ };
+ }
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 32ce11f..556f9f8 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,5 +1,8 @@
+import { NgReduxRouterModule } from '@angular-redux/router';
+import { NgReduxModule } from '@angular-redux/store';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
+import { NgxReduxStatePropsModule } from 'ngx-redux-state-props';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.router';
@@ -7,7 +10,14 @@ import { SharedModule } from './shared/shared.module';
@NgModule({
declarations: [AppComponent],
- imports: [AppRoutingModule, BrowserModule, SharedModule],
+ imports: [
+ AppRoutingModule,
+ BrowserModule,
+ SharedModule,
+ NgReduxModule,
+ NgReduxRouterModule.forRoot(),
+ NgxReduxStatePropsModule,
+ ],
providers: [],
bootstrap: [AppComponent],
})
From b0f2a7b7a104e402acf18fc2f458f02296d8174b Mon Sep 17 00:00:00 2001
From: Bruno Leonardo Michels
Date: Sun, 17 Jun 2018 18:58:07 -0300
Subject: [PATCH 3/6] Add actions and reducers
---
src/app/about/services/about.actions.ts | 34 +++++++++++++++++++++++++
src/app/about/services/about.reducer.ts | 25 ++++++++++++++++++
2 files changed, 59 insertions(+)
create mode 100644 src/app/about/services/about.actions.ts
create mode 100644 src/app/about/services/about.reducer.ts
diff --git a/src/app/about/services/about.actions.ts b/src/app/about/services/about.actions.ts
new file mode 100644
index 0000000..8fc6829
--- /dev/null
+++ b/src/app/about/services/about.actions.ts
@@ -0,0 +1,34 @@
+import { dispatch } from '@angular-redux/store';
+import { Injectable } from '@angular/core';
+
+const wait = (ms) => {
+ return new Promise((r) => setTimeout(r, ms));
+};
+
+@Injectable()
+export class AboutActions {
+ static readonly getApiValueType = 'getApiValueType';
+ static readonly apiSuccessType = 'apiSuccessType';
+
+ @dispatch()
+ getApiValue() {
+ console.log('ACTION: getApiValue');
+
+ const testTimeout = 1000;
+
+ return async (dispatcher) => {
+ await wait(testTimeout);
+ console.log('after 1s');
+ dispatcher(this.apiSuccess());
+ };
+ }
+
+ @dispatch()
+ apiSuccess() {
+ console.log('ACTION: apiSuccess');
+
+ return {
+ type: AboutActions.apiSuccessType,
+ };
+ }
+}
diff --git a/src/app/about/services/about.reducer.ts b/src/app/about/services/about.reducer.ts
new file mode 100644
index 0000000..4be51b8
--- /dev/null
+++ b/src/app/about/services/about.reducer.ts
@@ -0,0 +1,25 @@
+import { AboutActions } from './about.actions';
+
+export class AboutReducer {
+ [AboutActions.getApiValueType](state = {}, action) {
+ console.log('REDUCER: getApiValueType');
+
+ return {
+ ...state,
+ somethingFromReducer: 'foobar',
+ action,
+ };
+ }
+
+ [AboutActions.apiSuccessType](state = {}, action) {
+ console.log('REDUCER: apiSuccessType');
+ const offset = 32;
+
+ return {
+ ...state,
+ somethingFromReducer: 'foobar',
+ type: action.type,
+ action: Math.random().toString(offset),
+ };
+ }
+}
From 8f7dbfa17126a5a4d358544817856ec9574f2031 Mon Sep 17 00:00:00 2001
From: Bruno Leonardo Michels
Date: Sun, 17 Jun 2018 18:58:22 -0300
Subject: [PATCH 4/6] Add example of action call and values
---
src/app/about/about.component.html | 7 +++++++
src/app/about/about.component.ts | 15 ++++++++++++++-
src/app/about/about.module.ts | 2 ++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/app/about/about.component.html b/src/app/about/about.component.html
index f3b046b..315489e 100644
--- a/src/app/about/about.component.html
+++ b/src/app/about/about.component.html
@@ -3,3 +3,10 @@
This project shows you how to do things in Angular with full diff examples in commits/pull requests, with instructions included.
+
+
+
+
+
App State
+
{{ state | json }}
+
diff --git a/src/app/about/about.component.ts b/src/app/about/about.component.ts
index 1eab16f..c3ac19c 100644
--- a/src/app/about/about.component.ts
+++ b/src/app/about/about.component.ts
@@ -1,8 +1,21 @@
import { Component } from '@angular/core';
+import { NgxReduxStatePropsService } from 'ngx-redux-state-props';
+
+import { AboutActions } from './services/about.actions';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss'],
})
-export class AboutComponent {}
+export class AboutComponent {
+ constructor(private actions: AboutActions, private redux: NgxReduxStatePropsService) {}
+
+ get state() {
+ return this.redux.appState;
+ }
+
+ testRedux() {
+ this.actions.getApiValue();
+ }
+}
diff --git a/src/app/about/about.module.ts b/src/app/about/about.module.ts
index 90e5d05..1904eaa 100644
--- a/src/app/about/about.module.ts
+++ b/src/app/about/about.module.ts
@@ -3,9 +3,11 @@ import { NgModule } from '@angular/core';
import { AboutComponent } from './about.component';
import { RoutingModule } from './about.router';
+import { AboutActions } from './services/about.actions';
@NgModule({
imports: [RoutingModule, CommonModule],
declarations: [AboutComponent],
+ providers: [AboutActions],
})
export class AboutModule {}
From 10eedbe26692f7e104a9ed18c8f6030348600875 Mon Sep 17 00:00:00 2001
From: Bruno Leonardo Michels
Date: Sun, 17 Jun 2018 19:21:58 -0300
Subject: [PATCH 5/6] Update ngx-redux-state-props to 0.0.3 to handle null
checks
---
package-lock.json | 6 +++---
package.json | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 62ce5f3..6ff572e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8216,9 +8216,9 @@
"dev": true
},
"ngx-redux-state-props": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/ngx-redux-state-props/-/ngx-redux-state-props-0.0.2.tgz",
- "integrity": "sha512-dI/ythdbhrrSdurJXWb/1l9gpBV4s00p+sQDUylmIm8JlMDgKGS/DTVvvU5H12wnZwA0dWMor5qdNvauGEh8rg==",
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/ngx-redux-state-props/-/ngx-redux-state-props-0.0.3.tgz",
+ "integrity": "sha512-lTZroWvB664/yHK9sbxg48LSi46I9J3Q5Irw8GI0i0javvD7zf5txX4kjdkF52XRdkcd1z6VFj38ognPtnOD1A==",
"requires": {
"tslib": "^1.9.0"
}
diff --git a/package.json b/package.json
index 413bfc5..6cb1714 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
"@angular/router": "^6.0.5",
"bootstrap": "^4.0.0-beta.2",
"core-js": "^2.4.1",
- "ngx-redux-state-props": "0.0.2",
+ "ngx-redux-state-props": "0.0.3",
"ngx-take-until-destroy": "^3.0.0",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0",
From 420e67de74bf86ae95322b1e03c77ccf336fe666 Mon Sep 17 00:00:00 2001
From: Bruno Leonardo Michels
Date: Sun, 17 Jun 2018 19:22:10 -0300
Subject: [PATCH 6/6] Fix tests
---
src/app/about/about.component.spec.ts | 3 +++
src/app/app.component.spec.ts | 14 +++++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/app/about/about.component.spec.ts b/src/app/about/about.component.spec.ts
index 190d37a..9cb2f9a 100644
--- a/src/app/about/about.component.spec.ts
+++ b/src/app/about/about.component.spec.ts
@@ -1,6 +1,8 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { NgxReduxStatePropsService } from 'ngx-redux-state-props';
import { AboutComponent } from './about.component';
+import { AboutActions } from './services/about.actions';
describe('AboutComponent', () => {
let component: AboutComponent;
@@ -9,6 +11,7 @@ describe('AboutComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AboutComponent],
+ providers: [AboutActions, NgxReduxStatePropsService],
}).compileComponents();
}));
diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts
index b21615c..1d0760a 100644
--- a/src/app/app.component.spec.ts
+++ b/src/app/app.component.spec.ts
@@ -1,13 +1,25 @@
+import { NgReduxRouterModule } from '@angular-redux/router';
+import { NgReduxModule } from '@angular-redux/store';
import { async, TestBed } from '@angular/core/testing';
+import { BrowserModule } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
+import { NgxReduxStatePropsModule } from 'ngx-redux-state-props';
import { AppComponent } from './app.component';
+import { SharedModule } from './shared/shared.module';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
- imports: [RouterTestingModule],
+ imports: [
+ RouterTestingModule,
+ BrowserModule,
+ SharedModule,
+ NgReduxModule,
+ NgReduxRouterModule.forRoot(),
+ NgxReduxStatePropsModule,
+ ],
}).compileComponents();
}));