Skip to content

Instantly share code, notes, and snippets.

@Sawtaytoes
Created September 27, 2019 14:44
Show Gist options
  • Save Sawtaytoes/b9a2d61bb6902111d96c6b1f7b97eeaf to your computer and use it in GitHub Desktop.
Save Sawtaytoes/b9a2d61bb6902111d96c6b1f7b97eeaf to your computer and use it in GitHub Desktop.
Comparison of item storage techniques

The goal of this Gist is to figure out which items storage technique is a best-practice or good recommendation for taking a list of items and storing them into an asynchronous data storage.

There are various goals to accomplish such as reducing indirection, creating distinct micro-epics (each with their own job), and having an overall simpler time maintaining the code.

I've put together 2 examples of how you might handle storing a list of items with epics. A third example was added to show what one of the versions would look like with the ability to know when those items are done storing.

const storeItemsEpic = (
action$,
) => (
action$
.pipe(
ofType(STORE_ITEMS),
tap(newItems => {
retrieveFromStorage(
'items',
)
.pipe(
map(items => (
items
.concat(newItems)
)),
mergeMap(saveToStorage),
mergeMap(() => (
from(newItems)
.pipe(
pluck('itemId'),
toArray(),
)
)),
map(itemsSaved),
)
}),
)
)
const storeItemEpic = (
action$,
) => (
action$
.pipe(
ofType(STORE_ITEM),
map(item => (
storeItems([
item,
])
)),
)
)
const storeItemsEpic = (
action$,
) => (
action$
.pipe(
ofType(STORE_ITEMS),
mergeAll(),
map(storeItem),
)
)
const storeItemEpic = (
action$,
) => (
action$
.pipe(
ofType(STORE_ITEM),
mergeMap(({
item,
}) => (
retrieveFromStorage(
'items',
)
.pipe(
map(items => (
items
.concat(item)
)),
mergeMap(saveToStorage),
mapTo(
item
.itemId
),
map(itemSaved),
)
)),
)
)
const storeItemsEpic = (
action$,
) => (
action$
.pipe(
ofType(STORE_ITEMS),
mergeMap(({
groupId = Math.random(),
items,
}) => (
merge(
(
of(
savingItems({
items,
groupId,
})
)
),
(
from(items)
.pipe(
map((
item,
) => (
storeItem({
groupId,
item,
})
))
)
),
)
)),
)
)
const storeItemEpic = (
action$,
) => (
action$
.pipe(
ofType(STORE_ITEM),
tap(({
groupId,
item,
}) => {
retrieveFromStorage(
'items',
)
.pipe(
map(items => (
items
.concat(item)
)),
mergeMap(saveToStorage),
mapTo({
groupId,
itemId: (
item
.itemId
)
}),
map(itemSaved),
)
)),
)
)
const storeItemsCompleteEpic = (
action$,
) => (
action$
.pipe(
ofType(SAVING_ITEMS),
mergeMap((
items,
groupId,
) => (
action$
.pipe(
ofType(ITEM_SAVED),
filter(({
groupId: itemGroupId,
}) => (
itemGroupId === groupId
)),
scan(
numberOfSavedItems => (
numberOfSavedItems + 1
),
0,
)),
filter((
numberOfSavedItems,
) => (
numberOfSavedItems === items.length
)),
mapTo(items),
map(itemsSaved),
)
)),
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment