Singles

Singles are perhaps the most versatile Module type that Providence provides. Singles allow you to represent an arbitrary data structure in your state manager without creating extra boilerplate for their maintenance.

Singles are commonly composed into Lists.

Single Controllers

As with all Providence modules, you will want to interact with Singles through their controllers.

To get a new single controller:

Single Module Options

In most cases, you’ll only need to hand the retrieval function the endpoint of the object you’re retrieving, but you may also need to set a number of other attributes.

class SingleModuleOptions()

The construction parameters are mostly state that the SingleModule will be initialized with. This contains both the data of both the singleton itself and meta information about its status and how it is to be managed.

interface

SingleModuleOptions.attempted?

type: boolean

Indicates whether we have attempted to fetch the data from its endpoint before.

SingleModuleOptions.deleted?

type: boolean

Indicates that the resource this single is tracking has been deleted.

SingleModuleOptions.endpoint?

type: string

The URL for the endpoint this single tracks. You can set this to # if you’re only using this single for local state management. This will prevent the patchers from making bogus network requests.

SingleModuleOptions.failed?

type: boolean

Indicates that our attempt to fetch the data has failed.

SingleModuleOptions.fetching?

type: boolean

Indicates whether we are currently waiting on the data to load from its endpoint.

SingleModuleOptions.params?

type: <TODO: other type>|QueryParams

The query string parameters used when performing network operations on the endpoint.

SingleModuleOptions.persistent?

type: boolean

If set to true, the registry will not remove this module even if all listening components are removed.

SingleModuleOptions.ready?

type: boolean

Indicates that we have fetched the component and x is now ready.

SingleModuleOptions.x?

type: <TODO: other type>|T

Initial value for x, which is the data structure the module is tracking.

Default: null

Controller Reference

The single controller is the main interface by which you interact with the single module– and thus your state management library. Check here for a primer on controllers as a concept.

class SingleController()

interface

Extends:
  • BaseController()

SingleController.deleted

type: boolean

getter/setter to indicate whether the remote value we’re tracking has been deleted.

SingleController.endpoint

type: string

The endpoint property on the single module. This is a getter/setter, so you can update the endpoint.

SingleController.errors

type: default

Retrieves the stored error information from our last attempt at getting the remote object.

SingleController.failed

type: boolean

getter/setter to indicate that the attempt to fetch x failed. Can be set manually if needed for testing.

SingleController.fetching

type: boolean

getter/setter to indicate that x is being fetched via get request. Can be set manually if needed for testing.

SingleController.moduleType

type: <TODO: other type>

Returns ‘single’, the type of module this controller handles.

SingleController.p

type: BoundPatchers<T>

A proxy object that creates patchers for any property on the object. So, for instance, if you have a type:

  declare interface MyType {
    id: number,
    name: string,
    fun: boolean,
  }

Then this object will contain the keys `id`, `name`, and `fun`. Each of these attributes will be a
:js:class:`Patcher` bound to its specific field.
SingleController.params

type: <TODO: other type>|QueryParams

getter/setter for query parameters used when interacting with the endpoint.

SingleController.ready

type: boolean

getter/setter to indicate that x is initialized and ready to be interacted with. Mostly set internally, but can be explicitly set during testing.

SingleController.x

type: <TODO: other type>|T

The data structure you’re tracking in the single module. It can also be null if you’ve neither fetched nor preset its value. This is a getter and setter, so you can entirely replace x if you like.

Note that you should not mutate the attributes of x directly. Instead, if you need to change x, use updateX, :js:attr`setX <SingleController.setX>`, set the x setter directly, or use the Patchers.

SingleController.delete()

Sends a deletion request to the server. If successful, marks x as null and sets the deleted flag to true and sets the deleted flag to true.

Returns

Promise<void>

SingleController.get()

Performs a get request. Will update the value of x based on what it retrieves, and return a promise containing the new value.

Returns

Promise<T>

SingleController.getOnce()

Fetch this object from its endpoint. No matter how many times this function is called, it only runs once, allowing you to call it in any component that may need the function and not worry about several requests being sent.

SingleController.initializePatcherSettings(attrName)

Initialize a patcher’s settings. You might need this if the object returned from your initial fetching is incomplete and does not have the field you want to add a patcher for, or if you need to initialize a patcher without fetching the remote resource for some reason.

Arguments
  • attrName (AttrName()) –

SingleController.makeReady(val)

Set x and mark :js:attr`ready <SingleController.ready>` as true. Mostly useful for testing.

Arguments
  • val (T()) –

SingleController.patch(val)

Sends a patch request. Updates x with the value returned from the server, and returns a promise containing the new value.

Arguments
  • val (Partial) –

Returns

Promise<T>

SingleController.post(val)

Sends a post request. DOES NOT update x with the value returned from the server. Returns a promise containing the value the server sent back.

Arguments
  • val (I()) –

Returns

Promise<AxiosResponse<O, any>>

SingleController.put(val)

Sends a put request. Updates x with the value returned from the server, and returns a promise containing the new value.

Arguments
  • val (Partial) –

Returns

Promise<T>

SingleController.resetErrors()

Empties out the values in errors.

SingleController.setX(val)

Completely replace x.

Arguments
  • val (<TODO: other type>|T()) –

SingleController.updateX(val)

Update the value of x in place by setting a subset of its values.

Arguments
  • val (Partial) –

Patchers

Patchers are a special, controller-like wrapper around the attributes of singles. They act as proxies for sending patch requests to a server. This is especially useful for cases like Vue’s v-model, but also allows for more terse functions in the case of React’s event listeners.

Say you had a controller for a Product type:

declare interface Product {
  id: number,
  name: string,
  description: string,
  hidden: boolean,
}

You could update the value of hidden by setting its value on the autogenerated patcher:

// Output: false
console.log(controller.x.hidden)

controller.p.hidden.model = true
// Output: true
console.log(controller.p.hidden.model)
// Still false, as this value is canonical until the server update is completed:
console.log(controller.x.hidden)
// Also true, since the update is not complete:
console.log(controller.p.hidden.dirty)

The value on a Patcher’s model field is instantly updated, and in the background, a patch request is dispatched to the endpoint with the data {“hidden”: true}.

Up until the patcher succeeds, its dirty flag stays true. If an error occurs while performing the patch request, errors will appear in controller.p.hidden.errors. See below for more attributes and methods.

class Patcher()

A wrapper class around individual attributes on a single.

interface

Patcher.attrName

type: AttrName

The name of the field we’re tracking on the single.

Patcher.cached

type: <TODO: other type>|<TODO: other type>

The most recently set value on the field through the patcher. Compared against the real value on the single x’s field to determine if the value is :js:attr`dirty`.

Patcher.controller

type: SingleController<T>

A reference to the SingleController, used for internal functions.

Patcher.debouncedRawSet

type: DebouncedFunc<<TODO: reflection>>

The debounced function that set calls. You usually don’t want to call this directly. If you do, you’ll probably want to set cache first.

Patcher.dirty

type: boolean

A getter that returns true if the cached value does not match the value on the single’s x.

Patcher.errors

type: string[]

An array of derived errors from the server when trying to patch this field.

Patcher.loaded

type: boolean

Whether the underlying value has been loaded successfully (that is, is x set on the SingleController()?)

Patcher.model

type: <TODO: other type>

A getter and setter that invokes the patch requesting machinery. That is, set this value to send a patch request.

This value will return the cached value. Setting this value is equivalent to running set.

Patcher.moduleType

type: <TODO: other type>

Returns ‘patcher’, the type of ‘module’ this wrapper handles. Technically patchers aren’t modules, since their state is shared with singles, however this makes it consistent with similarly behaving controllers, which should have a moduleType property for easy identification.

Patcher.patching

type: boolean

Whether a patch request is currently being sent. You might use this to determine whether a spinner should be shown.

Patcher.rawValue

type: <TODO: other type>

Gets the current value of the :js:attr`attrName` field on x.

Patcher.rawSet(val)

The raw set function that debouncedSet debounces. You usually don’t want to call this directly. If you do, you’ll probably want to set cache first. This function performs the actual patch request and handles the resulting server response.

Arguments
  • val (<TODO: other type>()) –

Patcher.set(val)

Sets a new value for the field, updating the cache and then running debouncedSet.

Arguments
  • val (<TODO: other type>()) –