ValidatingStore

open class ValidatingStore<D, T, M>(initialData: D, validation: Validation<D, T, M>, metadataDefault: T, job: Job, validateAfterUpdate: Boolean = true, val id: String = Id.next()) : RootStore<D>

A ValidatingStore is a Store which also contains a Validation for its model and by default applies it to every update.

This store is intentionally configured to validate the data on each update, that is why the validateAfterUpdate parameter is set to true by default.

There might be special situations where it is reasonable to disable this behaviour by setting validateAfterUpdate to false and to prefer applying the validation individually within custom handlers, for example if a model should only be validated after the user has completed his input or if metadata is needed for the validation process. Then be aware of the fact, that the call of the validate function actually updates the messages already.

In order for the automatic validation to work, a metadataDefault value must be specified. This is needed due to no specific metadata being present during automatic validation. When calling validate manually, the appropriate metadata can be supplied directly.

If the new data is not passed to the store's state after validating it, the messages are probably out of sync with the actual store's state! This could lead to false assumptions and might produce hard to detect bugs in your application.

Parameters

initialData

first current value of this Store

validation

Validation function to use at the data on this Store.

metadataDefault

default metadata to be used by the automatic validation (where no explicit values are given)

job

Job to be used by the Store

validateAfterUpdate

flag to decide if a new value gets automatically validated after setting it to the Store.

id

id of this Store. Ids of parent Stores will be concatenated.

Constructors

Link copied to clipboard
constructor(initialData: D, validation: Validation<D, T, M>, metadataDefault: T, job: Job, validateAfterUpdate: Boolean = true, id: String = Id.next())

Properties

Link copied to clipboard
open override val current: D

Represents the current data of this Store.

Link copied to clipboard
override val data: Flow<D>

Emits a Flow with the current data of this Store. The Flow internal data is only changed, when the value differs from the last one to avoid calculations and updates that are not necessary.

Link copied to clipboard
open override val id: String
Link copied to clipboard
override val job: Job

Job used as parent job on all coroutines started in Handlers in the scope of this Store

Link copied to clipboard
val messages: Flow<List<M>>

Flow of the List of validation-messages. Use this Flow to render out the validation-messages and to detect the valid state of the current data.

Link copied to clipboard
open override val path: String

Path of this Store derived from the underlying model. Paths of depending Stores are concatenated and separated by a dot.

Link copied to clipboard
open override val update: SimpleHandler<D>

a simple SimpleHandler that just takes the given action-value as the new value for the Store.

Functions

Link copied to clipboard
open suspend override fun enqueue(update: Update<D>)

in a RootStore an Update is handled by applying it to the internal StateFlow.

Link copied to clipboard
open fun errorHandler(cause: Throwable)

Default error handler printing the error to console.

Link copied to clipboard
open fun handle(execute: suspend (D) -> D): SimpleHandler<Unit>

Factory method to create a SimpleHandler that does not take an Action

open fun <A> handle(execute: suspend (D, A) -> D): SimpleHandler<A>

Factory method to create a SimpleHandler mapping the actual value of the Store and a given Action to a new value.

Link copied to clipboard
open fun <E> handleAndEmit(execute: suspend FlowCollector<E>.(D) -> D): EmittingHandler<Unit, E>

factory method to create an EmittingHandler that does not take an action in it's execute-lambda.

open fun <A, E> handleAndEmit(execute: suspend FlowCollector<E>.(D, A) -> D): EmittingHandler<A, E>

Factory method to create a EmittingHandler taking an action-value and the current store value to derive the new value. An EmittingHandler is a Flow by itself and can therefore be connected to other SimpleHandlers even in other Stores.

Link copied to clipboard
fun <D> Store<D>.history(capacity: Int = 0, initialEntries: List<D> = emptyList(), job: Job = this.job, synced: Boolean = true): History<D>

factory-method to create a History synced with the given Store, so that each update is automatically stored in history.

Link copied to clipboard
open fun <X> map(lens: Lens<D, X>): Store<X>

Creates a new Store that contains data derived by a given Lens.

Link copied to clipboard
fun <P, T> Store<P?>.map(lens: Lens<P & Any, T>): Store<T>

on a Store of nullable data this creates a Store with a nullable parent and non-nullable value. It can be called using a Lens on a non-nullable parent (that can be created by using the @Lenses-annotation), but you have to ensure, that the resulting Store is never used, when it's parent's value is null. Otherwise, a NullPointerException is thrown.

Link copied to clipboard
fun <D, I> Store<List<D>>.mapByElement(element: D, idProvider: IdProvider<D, I>): Store<D>

Creates a new Store containing the element for the given element and idProvider from the original Store's List.

Link copied to clipboard
fun <D> Store<List<D>>.mapByIndex(index: Int): Store<D>

Creates a new Store containing the element for the given index from the original Store's List

Link copied to clipboard
fun <K, V> Store<Map<K, V>>.mapByKey(key: K): Store<V>

Creates a new Store containing the corresponding value for the given key from the original Store's Map.

Link copied to clipboard
fun <T> Store<T?>.mapNull(default: T): Store<T>

Creates a new Store from a nullable parent store that either contains the original value or a given default value if the original value was null.

Link copied to clipboard
fun <M : ValidationMessage> Store<*>.messages(): Flow<List<M>>?

Finds all exactly corresponding ValidationMessages to this Store, which means all messages, which have exactly the same path as the Store.

fun <M : ValidationMessage> Store<*>.messages(filterPredicate: (M) -> Boolean): Flow<List<M>>?

Finds all corresponding ValidationMessages to this Store which satisfy the filterPredicate-expression.

Link copied to clipboard

Finds all corresponding ValidationMessages to this Store, which means all messages, that fit exactly with their path or which are sub-elements of this Stores data model.

Link copied to clipboard
fun runWithJob(init: WithJob.() -> Unit)

Allows to use the WithJob-Context of this Store and to run handledBy on the Store-Job