$ngRedux
Bob & Ash
Angular State Problems
- What is the state?
- Where is the state?
- How to update the state?
Looking forward
- Angular 2
- Less dependant on Angular 1
- Smart / dumb components
Redux + Angular
Demo simple phones app
angular.module('starter')
.config(appConfig);
appConfig.$inject = ['$ngReduxProvider', 'rootReducerProvider'];
function appConfig($ngReduxProvider, rootReducerProvider) {
$ngReduxProvider.createStoreWith(rootReducerProvider.$get(), [
'promiseMiddleware',
'loggerMiddleware'
]);
}
Configuration
angular.module('starter')
.factory('rootReducer', rootReducer);
rootReducer.$inject = ['phonesReducer'];
function rootReducer(phonesReducer) {
return Redux.combineReducers({
phones: phonesReducer
});
}
Root Reducer
...
function reducer(state, action) {
var initialState = {
phones: []
};
if (angular.isUndefined(state)) {
return angular.copy(initialState);
}
switch (action.type) {
case 'CREATE_PHONE':
state.phones.push(action.payload);
break;
case 'SET_PHONES_FULFILLED' :
state = angular.copy(action.payload);
break;
}
return state;
}
Reducer
...
function PhonesController($scope, $ngRedux) {
var vm = this;
var unsubscribe = $ngRedux.connect(mapStateToVm)(vm);
$scope.$on('$destroy', unsubscribe);
function mapStateToVm(state) {
return {
phones: state.phones
};
}
}
Connect state to VM
...
function phonesActions(phonesService) {
return {
createPhone: createPhone,
setPhones: setPhones
};
function createPhone(phone) {
return {
type: 'CREATE_PHONE',
payload: phone
};
}
function setPhones() {
return {
type: 'SET_PHONES',
payload: {
promise: phonesService.getPhones()
}
};
}
}
Action creators
...
function PhonesController($scope, $ngRedux, phonesActions) {
var vm = this;
var unsubscribe = $ngRedux.connect(mapStateToVm, phonesActions)(vm);
vm.onSubmit = onSubmit;
$scope.$on('$destroy', unsubscribe);
vm.setPhones();
function mapStateToVm(state) {
return {
phones: state.phones
};
}
function onSubmit(phone) {
vm.createPhone(phone);
}
}
Dispatch actions from VM
<h1 ng-bind="vm.title"></h1>
<form name="phoneCreateForm" ng-submit="vm.onSubmit(vm.newPhone)">
<input type="text" name="title" autocomplete="off" ng-model="vm.newPhone"/>
<button type="submit">Create phone</button>
</form>
<ul>
<li ng-repeat="phone in vm.phones" ng-bind="phone"></li>
</ul>
Template
function thunkMiddleware(store) {
return function (next) {
return function (action) {
if (typeof action === 'function') {
return action(store.dispatch, store.getState);
}
return next(action);
};
};
}
Middleware
Benefits
- Easy unit testing
- Powerful middleware
- Discoverable set of actions
- Asynchronous state representation
- Improved reliability
Goodies
Let's start hacking
- Combine reducers
- Set initial state for stories
- Connect Main component to vm
- Fetch stories using redux
- Create STORY_FINISHED action
- Pass action through to components
- Add unit tests
- Show loading indicator
- Create time out for notification
Workshop steps
ng-redux session
By Bob Bijvoet
ng-redux session
- 2,381