Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/aknuds1/choo-routehandler

A minimal WIP route handling framework on top of choo
https://github.com/aknuds1/choo-routehandler

choo framework javascript routing

Last synced: 5 days ago
JSON representation

A minimal WIP route handling framework on top of choo

Awesome Lists containing this project

README

        

# choo-routehandler
This is a small route handling framework on top of [Choo](https://github.com/yoshuawuyts/choo).
Beware it's a work in progress and likely to change!!

The core feature of this framework is that it provides a function for wrapping your route handlers,
mitigating the need for writing boilerplate code. It requires three arguments: `view`, `loader`
and `layout`. You can also pass an options object as the fourth argument.


view

Either a function, for rendering the view corresponding to the route, or a module containing
at least a function render fulfilling the aforementioned responsibility, optionally
a function loadData for loading data pertaining to the route before rendering it and
optionally a function or attribute pageTitle for defining a route's page title.
The loadData function should return a promise resolving to an object to patch Choo state with.

loader

An argument free function that should return a DOM element representing a loading screen.

layout

A function representing the layout of the view, that should take four arguments, the rendered
view, state, prev and send, and return a DOM element.

opts

An object providing options to the route handler. The following options are supported:

  • requiresLogin: Configure whether the route requires the user to be logged in.

  • isUserLoggedIn: A function taking state as its argument, returning whether
    the user is logged in or not.

  • loginUrl: The URL to redirect to if the route requires login and user hasn't yet been
    logged in.



## Route Rendering

The route handler wrapper renders the view for your route inside a container element,
`#route-container`, possessing an attribute called `data-route`, which encodes the current route
and query string. It also registers a callback via a
[MutationObserver](https://developer.mozilla.org/en/docs/Web/API/MutationObserver) that triggers
when said attribute changes, in order to react as the rendered route changes. The reaction is
implemented as a Choo effect `handleRouteLoadedIntoDom`, which gets defined in the _model_ part
of the framework.

The behaviour of the route handler is to, once it detects that the currently rendered route changes
(including its query string), go through a standard procedure in order to render the corresponding
view, depending on whether or not there is a data loading hook for the route:

### With a Data Loading Hook
1. Invoke the `loadData` hook and render the loading view.
2. Once the `loadData` promise resolves, merge the resulting state subgraph into the Choo state
graph. Then call the `render` hook in order to render the view corresponding to the route.

### Without a Data Loading Hook
Just render the view corresponding to the route.

## The Model
The model, defined in the model.js file of the package (import as e.g.
`require('@arve.knudsen/choo-routehandler/model')`), defines state/effects/reducers required
by the framework.

## Example
```
const routeHandler = require('@arve.knudsen/choo-routehandler')
const routeHandlerModel = require('@arve.knudsen/choo-routehandler/model')
const app = require('choo')

const loading = require('./loading')
const layout = require('./layout')

app.model({
state: {...}
})
routeHandlerModel(app)

app.router({default: '/404',}, [
['/404', routeHandler(notFoundView, loading, layout),],
['/', routeHandler(mainView, loading, layout),],
])
```