Feasgar Math!
Good afternoon!
I am thrilled to be here today.
My name is Cory and I am a senior web developer at Aumni.
and I am learning Scottish Gaelic. 😄
cory brown
why yes, we are hiring. thank you for asking
How to understand more by thinking less
or
5-ish best practices for managing complexity
Our subject
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then((pageData) => {
updateAppState(pageData)
if (pageData.user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = pageData.transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
How to reduce complexity
- Don't artificially entangle state
- Pass only what is absolutely needed
- Derive what can be derived
- Push effects (error handling, fetching, etc) toward the edges
- Dependency Injection
Don't artificially entangle state
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then((pageData) => {
updateAppState(pageData)
if (pageData.user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = pageData.transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
response.json()
.then(errorMessage => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(errorMessage)
done(errorMessage)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(error)
done(error)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
[My app] cannot be reconciled with the idea that [app state] should represent a reality in time and space, free from spooky action at a distance
~ Einstein the software developer
How not to artificially entangle state
combineReducers(userReducer, transactionsReducer)
...
dispatch({ type: 'user', paylaod: user })
dispatch({
type: 'transactions',
paylaod: transactions
})
combined reducers + dispatch
(props) => {
const [user, setUser] = useState(null)
const [
transactions,
setTransactions
] = useState(null)
...
}
distinct useState/Reducer calls
MyStore.getMyStuff()
MySore.on('change', handler)
YourStore.getYourStuff()
YourSore.on('change', handler)
separate data stores
How not to artificially entangle state
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (pageData.user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
response.json()
.then(errorMessage => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(errorMessage)
done(errorMessage)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(error)
done(error)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then((pageData) => {
updateAppState(pageData)
if (pageData.user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = pageData.transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
response.json()
.then(errorMessage => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(errorMessage)
done(errorMessage)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(error)
done(error)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Pass only what is needed
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Law of Demeter
(The principle of least knowledge)
A given object should assume as little as possible about the structure or properties of anything else (including its subcomponents).
Stuff goes in
Stuff comes out
?
Stuff goes in
Stuff comes out
Stuff goes in
Stuff comes out
?
global scope?
mutations?
Pass only what is needed
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const hasError = (message: MESSAGE_TYPE): boolean => (
message.status === UNKNOWN_ERROR ||
message.status === UNKNOWN_STATUS ||
message.status === ERROR
)
const hasError = (messageStatus: MESSAGE_STATUS_ENUM): boolean => (
messageStatus === UNKNOWN_ERROR ||
messageStatus === UNKNOWN_STATUS ||
messageStatus === ERROR
)
const hasError = (messageStatus: MessageStatusEnum) =>
[UNKNOWN_ERROR, UNKNOWN_STATUS, ERROR].includes(messageStatus)
const hasError = (message: MESSAGE_TYPE): boolean => (
message.status === UNKNOWN_ERROR ||
message.status === UNKNOWN_STATUS ||
message.status === ERROR
)
Pass only what is needed
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataEndpoints, adminRole, done) => {
fetch(pageDataEndpoints[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (user.role === adminRole) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (user.role === adminRole) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (isAdmin(user.role)) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (isAdmin(user)) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Pass only what is needed
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (isAdmin(user.role)) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Derive what can be derived
To produce or obtain (a compound) from another substance
Derive what can be derived
What's a googol minus 1?
- my 7yr old
😅
- Alexa
Derive what can be derived
What's a googol minus 1?
- my 7yr old
999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999
- the answer he was looking for
Derive what can be derived
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (isAdmin(user.role)) {
setIsAdmin(true)
}
const transactionsPreview = transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
if (isAdmin(user.role)) {
setIsAdmin(true)
}
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Side Effects === complexity
A place for everything, and everything in its place
- Benjamin Franklin
Push effects toward the edge
Pure.
Less pure.
Push effects toward the edge
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Push effects toward the edge
Promise.resolve(
Promise.resolve(
Promise.resolve(
Promise.resolve(
Promise.resolve(
Promise.resolve(5)
)
)
)
)
).then((val) => console.log(val))
// 5
Push effects toward the edge
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Push effects toward the edge
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => {
if (response.ok) {
response.json()
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok ? response.json() : Promise.reject(response))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok ? response.json() : Promise.reject(response))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Push effects toward the edge
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok ? response.json() : Promise.reject(response))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok ? response.json() : Promise.reject(response))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get user.`)
log(error)
done(error)
})
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Before/After
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (endpoints, pageName, roles, featureFlags, done) => {
fetch(endpoints.pageData[pageName])
.then((response) => {
if (response.ok) {
response.json()
.then((pageData) => {
updateAppState(pageData)
if (pageData.user.role === roles.admin) {
setIsAdmin(true)
}
const transactionsPreview = pageData.transactions.slice(0, 3)
setTransactionsPreview(transactionsPreview)
done()
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't parse page data.`)
log(error)
done(error)
})
} else {
globalErrorToast(`Oh noes! Couldn't get user.`)
response.text()
.then(errorMessage => {
log(errorMessage)
done(errorMessage)
})
}
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
Dependency Injection
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const makeGetPageData = ({
fetch,
updateUser,
updateTransactions,
globalErrorToast,
log
}) => (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
}
Dependency Injection
const makeGetPageData = ({
fetch,
updateUser,
updateTransactions,
globalErrorToast,
log
}) => (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
}
Bonus: Prefer return values to callbacks
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI, done) => {
fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
done()
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
done(error)
})
}
const getPageData = (pageDataURI) => fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions, ...rest }) => {
updateUser(user)
updateTransactions(transactions)
return { user, transactions, ...rest }
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
})
Super double bonus: tap
const tap = (fn) => (value) => {
fn(value)
return value
}
Super double bonus: tap
const getPageData = (pageDataURI) => fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(({ user, transactions, ...rest }) => {
updateUser(user)
updateTransactions(transactions)
return { user, transactions, ...rest }
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
})
const getPageData = (pageDataURI) => fetch(pageDataURI)
.then((response) => response.ok
? response.json()
: Promise.reject(response.text()))
.then(tap({ user, transactions }) => {
updateUser(user)
updateTransactions(transactions)
})
.catch((error) => {
globalErrorToast(`Oh noes! Couldn't get page data.`)
log(error)
})
How to reduce complexity
- Don't artificially entangle state
- Pass only what is absolutely needed
- Derive what can be derived
- Push effects (error handling, fetching, etc) toward the edges
- Dependency Injection
- Prefer return values to callback
- tap is cool
Are there any questions?
A bheil ceistean ann?
agus
thank you
Tapadh leibh
Beannach leibh uile
goodbye everyone
and
Understand More By Thinking Less
By Cory Brown
Understand More By Thinking Less
- 619