Skip to content

Peterabsolon/mobx-blocks

Repository files navigation

mobx-blocks (beta)

MobX classes designed for solving common problems encountered when building dashboard-style web applications. With 100% test coverage.

Collection

Given an async fetch function like:

type Product = { id: string }
type FetchFn = (params: Record<string, any>) => Promise<{ data: Product[] }>

We can pass it to a new Collection to let it manage the following:

Storing the data (boring on its own)

const products = new Collection({ fetchFn })
console.log(c.data) // type Product[] inferred from fetchFn return

Sorting

const products = new Collection({
  fetchFn,
  sortBy: "id" as "id" | "title",
})

products.sorting.sort("id") // fetchFn call (triggered automatically by reaction)
products.sorting.toggleDirection() // fetchFn call
products.sorting.setKey("title") // fetchFn call
products.sorting.setAscending(true) // fetchFn call

Filtering

const products = new Collection({
  fetchFn,
  initialFilters: { title: "Foo", valid: false } as ProductQueryParams,
})

products.filters.set("title", "Bar") // fetchFn call
products.filters.get("title")
products.filters.merge({ title: "Bar" }) // valid: false persists, fetchFn call
products.filters.replace({ title: "Bar" }) // valid:false gets removed, fetchFn call
products.filters.reset() // reset to initialFilters, fetchFn call

Selection

const products = new Collection({ fetchFn })

await products.fetch()

products.selection.select(products.data.?[0]) // added to selection
products.selection.select(products.data.?[0]) // removed from selection
products.selection.set(products.data) // select all products

Caching

import { Cache, Collection } from "mobx-blocks"

// The Cache will be our source of truth so we create it first and pass it to the Collection
const productsCache = new Cache({ ttl: 3 }) // in minutes
const products = new Collection({ fetchFn, fetchOne, cache: productsCache })

await products.fetch({ sortBy: "title", ascending: false }) // fetchFn call
await products.fetch({ sortBy: "title", ascending: false }) // called with same params -> result returned from Cache
await products.fetchOne("id") // given this id exists in cache no fetchOne call will be made
await products.fetchOne("id", { useCache: false }) // we can bypass this behaviour if the fetchOne returns more detailed data

synchronizing query params to URL

const products = new Collection({
  fetchFn,
  sortBy: "title",
  initialFilters: { foo: "foo", bar: "bar" },
  syncParamsToUrl: true, // TODO: pass filter function
})

products.fetch()

// ...URL now contains ?sortBy=title&sortAscending=true&foo=foo&bar=bar

TODO: initializing from query string

const products = new Collection({
  fetchFn,
  sortBy: null as null | "title",
  initialFilters: { foo: "", bar: "" },
})

products.init({ queryString: "?sortBy=title&sortAscending=true&foo=foo&bar=bar" })

console.log(products.sorting.params) // { sortBy: "title", ascending: true }
console.log(products.filters.active) // { foo: "foo", bar: "bar" }

Kitchen-sink example

Source

Types

Cache

[TODO] Manages caching of list/detail queries

Pagination

[TODO] Manages pagination

Filters

[TODO] Manages filters

Selection

[TODO] Manages filters

Notifications

[TODO] Manages notifications

Modals

[TODO] Manages modals

About

Building blocks for building MobX powered apps

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

No packages published