Skip to content

Instantly share code, notes, and snippets.

@pelid
Last active February 14, 2017 17:30
Show Gist options
  • Save pelid/97456099f90327d53f02e08acf5521e1 to your computer and use it in GitHub Desktop.
Save pelid/97456099f90327d53f02e08acf5521e1 to your computer and use it in GitHub Desktop.
Moscow JS presentation
let submitSaga = decorate(
_.partial(catchFormErrors, formStore),
preloader.createPreloaderWrapper(formStore),
function*(){
yield* credentials.CredentialsFormSubmitter(inputs)
formStore.dispatch({type: 'SUBMITTED'})
},
)
yield* submitSaga()
function* emailFormSaga({layout, store}){
let formStore = createStore(reducer)
const page = layout.mountPage('page-email_form.tag.html', {formStore})
let formChannel = observableChannel(page)
while (true){
const action = yield take(formChannel)
if (action.type!='submit')
continue
let inputs = _.fromPairs(action.payload)
let response = yield* api.post('/api/v1/user/set_email', inputs)
// if errors launch some common logic, otherwise
store.dispatch({type: 'PROFILE_UPDATED', payload: response.user})
}
}
const routesMiddlewares = [
showPlugIfFailure,
redirectsHandler.handler,
handler404.handler,
handleAPIAuthErrors.handler,
]
const sendQuoteSaga = decorate(
sanitizeParams(scheme),
blockingPreloader.blockTill([
({}, {orderId}) => fetchers.order(orderId),
], {message: 'Загружаем заказ'}),
function*({layout, store}, {next, orderId}){
const isAuthenticated = loginedUserSlct(store.getState())
if (!isAuthenticated)
yield* signUp({layout}, {orderId}) // ф-ция signUp тоже обернута декораторами
const hasEmail = credentials.hasEmail(store.getState())
if (!hasEmail)
yield* request4credentials({layout}) // и эта ф-ция тоже использует пачку декораторов
yield* sendQuote({layout}, {orderId}) // выкидывает исключение Redirect2URL
}
)
const wrapWithPreloader = saga => function*(...args){
let preloaderTask = function*(){
store.dispatch(taskStarted())
try {
yield delay(300) // delay is required in case of user data early validation fail
store.dispatch(taskAssumedLongRunning())
yield delay(maxDelay)
} finally {
store.dispatch(taskStoped({preloaderId}))
}
}
const {result, preloader} = yield race({
result: call(saga, ...args),
preloader: call(preloaderTask)
})
return result
}
import preloader from '../features/preloader'
import forms from '../features/forms'
import immutable from 'immutable'
const Initials = immutable.Record({
cellphone: '',
email: '',
})
const reducer = combineReducers({
errors: forms.createErrorsReducer(),
initials: forms.createInitialsReducer(Initials),
preloader: preloader.createReducer(),
isSubmited: (state=false, action)=>{
return action.type=='SUBMITTED' ? true : state
}
})
const store = createStore(reducer)
function reduceCounter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
let store = createStore(reduceCounter)
store.dispatch({ type: 'INCREMENT' }) // 1
store.dispatch({ type: 'INCREMENT' }) // 2
store.dispatch({ type: 'DECREMENT' }) // 1
function* routingSaga(routes, context){
// ... инициализируем routeChannel, туда попадают события изменения window.location
yield* takeLatest(routeChannel, function*({route, urlParams}){
let saga = selectPageSaga(route)
try {
yield* saga(context, {
urlParams,
queryParams: queryString.parse(query),
})
} catch (error){
// swallow exception for safety of parent saga
console && console.error && console.error(error)
}
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment