FabienHenon/app-object/2.0.0

Formerly calions-app/app-object. Search finds this package by either name.

AppObject

The AppObject is an object that encapsulates the Model and Cmd Msg of a component (returned in side effect functions like init or update) plus and appData object and a Cmd appMsg. These new elements are a model and commands related to the entire application.

Let's say for instance that you have a component that does something (whatever) and that needs to open a modal, or set the connected user, or set the user language of the application, ... All of these states/effects are related to the application, not to the component. Indeed, the component itself can't open a modal because it's the application's responsibility. Also, the component could save the connected user to its own state, but it's a data the entire application would like to know about and with the classic architecture of elm apps it's not possible for a component to tell the app that it should update its state.

To make it simpler: a component can't change the state of its parent component and can't send commands with its parent's messages.

This is what AppObject is for, it allows you to:

  • define a model that any component in the application can read and update
  • send commands that the root component can handle

Definitions

type AppObject appData appMsg model msg

AppObject is the object you should return from your side effect functions (init, update) in your components.

  • appData refers to the model you want to be global to your application. This model is usualy stored in your root state
  • appMsg refers to the msg type you want to be global to your application. This msg is usually handle in your root update function
  • model refers to the model of your current component
  • msg refers to the msg type of your current component

I suggest your create a module that defines your appData model and your appMsg message type, and you define a type alias of your own AppObject with the appData and appMsg set :

type alias MyAppObject model msg =
    AppObject.AppObject Data AppMsg model msg


type alias Data =
    { isModalOpen : Bool
    }


type AppMsg
    = ToggleModal Bool

Init

init : appData -> model -> AppObject appData appMsg model msg

Creates a new AppObject from the appData and your component's model

Cmd msg
-> AppObject appData appMsg model msg
-> AppObject appData appMsg model msg

Adds a new component's command to this AppObject

Cmd appMsg
-> AppObject appData appMsg model msg
-> AppObject appData appMsg model msg

Adds a new global command to this AppObject

(model -> ( model, Cmd msg ))
-> AppObject appData appMsg model msg
-> AppObject appData appMsg model msg

Adds a new component's command to this AppObject? The model is passed as parameter

(model -> ( model, Cmd appMsg ))
-> AppObject appData appMsg model msg
-> AppObject appData appMsg model msg

Adds a new global command to this AppObject. The model is passed as parameter

Mappers

map :
(modelA -> modelB)
-> (appDataA -> appDataB)
-> (msgA -> msgB)
-> (appMsgA -> appMsgB)
-> AppObject appDataA appMsgA modelA msgA
-> AppObject appDataB appMsgB modelB msgB

Maps your AppObject to change the types of appData, appMsg, model and msg

(a -> appData)
-> AppObject a appMsg model msg
-> AppObject appData appMsg model msg

Maps only your appData

(a -> appMsg)
-> AppObject appData a model msg
-> AppObject appData appMsg model msg

Maps only your appMsg

(a -> model)
-> AppObject appData appMsg a msg
-> AppObject appData appMsg model msg

Maps only your model

(a -> msg)
-> AppObject appData appMsg model a
-> AppObject appData appMsg model msg

Maps only your msg

Advanced usage

(modelB -> modelA -> modelC)
-> (appDataB -> appDataA -> appDataC)
-> (msgA -> msgC)
-> (msgB -> msgC)
-> (appMsgA -> appMsgC)
-> (appMsgB -> appMsgC)
-> AppObject appDataA appMsgA modelA msgA
-> AppObject appDataB appMsgB modelB msgB
-> AppObject appDataC appMsgC modelC msgC

Merges 2 AppObjects together. You provide the functions used to:

  • merge the model
  • merge the appData
  • map the msg
  • map the appMsg
( a
-> AppObject appData appMsg model msg
-> AppObject appData appMsg model msg
)
-> List a
-> AppObject appData appMsg model msg
-> AppObject appData appMsg model msg

Reducer that allows you to update or create an AppObject for each element of a list

(appDataA -> modelA -> AppObject appDataB appMsg modelB msg)
-> AppObject appDataA appMsg modelA msg
-> AppObject appDataB appMsg modelB msg

Allows you to create a new AppObject from an existing one, using the appData and the model. The new Cmd appMsg and Cmd msg will be batched to the existing ones

Usage

run :
(appData -> model -> model)
-> (appMsg -> msg)
-> AppObject appData appMsg model msg
-> ( model, Cmd msg )

Executes your AppObject. That means that you will create a ( model, Cmd msg ) tuple from an AppObject, this allows you to run your side effects and model updates in your root update and init functions