Skip to content

Instantly share code, notes, and snippets.

@andrejewski
Created March 3, 2018 17:39
Show Gist options
  • Select an option

  • Save andrejewski/dd5608615d3b8feab6af3fafff17a4d8 to your computer and use it in GitHub Desktop.

Select an option

Save andrejewski/dd5608615d3b8feab6af3fafff17a4d8 to your computer and use it in GitHub Desktop.
import React from 'react'
import react from 'raj-react'
import { union } from 'tagmeme'
import { mapEffect } from 'raj-compose'
export function loadModelsForMake (id) {
return function (dispatch) {
window.fetch(`/models?id=${id}`)
.then(res => res.json())
.then(res => {
dispatch(res.models)
})
}
}
export const Msg = union([
'SetMake',
'SetModels'
])
export const init = [{
makeId: null,
isLoading: false,
models: []
}]
export function update (msg, state) {
return Msg.match(msg, {
SetMake: makeId => [
{...state, makeId, isLoading: true},
mapEffect(loadModelsForMake(makeId), Msg.SetModels)
],
SetModels: models => [{
...state,
models,
isLoading: false
}]
})
}
export function view (state, dispatch) {
const makes = ['ford', 'honda', 'windows']
return <div>
<ul>
{makes.map(make =>
<li onClick={() => dispatch(Msg.SetMake(make))}>{make}</li>
)}
</ul>
state.isLoading && <p>Loading models...</p>
<ul>
{state.models.map(model => <li>{model.name}</li>)}
</ul>
</div>
}
export function main () {
return react.program(React.Component, () => ({
init,
update,
view
}))
}
import React from 'react'
import react from 'raj-react'
import { union } from 'tagmeme'
import { mapEffect } from 'raj-compose'
export const Result = union(['Ok', 'Err'])
export function fetchResults (query) {
return function fetchEffect (dispatch) {
return window.fetch(`/my/search/endpoint?query=${encodeURIComponent(query)}`)
.then(res => res.json())
.then(payload => {
dispatch(Result.Ok(payload.results))
})
.catch(error => {
dispatch(Result.Err(error))
})
}
}
export const Msg = union(['SetQuery', 'SetResults'])
export const init = [{
query: '',
results: [],
isLoading: false,
error: null
}]
export function update (msg, state) {
return Msg.match(msg, {
SetQuery: query => [
{ ...state, query, isLoading: true },
mapEffect(fetchResults(query), Msg.SetResults)
],
SetResults: result => {
const newState = { ...state, isLoading: false, error: null }
return Result.match(result, {
Ok: results => [{ ...newState, results }],
Err: error => [{ ...newState, error }]
})
}
})
}
export function view (state, dispatch) {
return <div>
<input {...{
value: state.query,
onChange: event => {
dispatch(Msg.SetQuery(event.target.value))
}
}} />
<ul>
{state.results.map(result =>
<li key={result}>{result}</li>
)}
</ul>
</div>
}
export function main () {
return react.program(React.Component, () => ({
init,
update,
view
}))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment