An NgRx based State Machine for Angular Components - Part 2
In Part 1 I looked at extending the NgRx ActionsSubject to form the basis of a finite state machine for controlling UI state.
The next part of the puzzle was to provide a way for components to register the particular actions they were interested in, and how each action should transition the current state of the component. Initially this started with a javascript object literal:
In the above object declaration a userApproval component declares an interest in three actions, loadUnapprovedUsers, loadUnapprovedUsersSuccess, and loadUnapprovedUsersError.
In the case of loadUnapprovedUsers action, the component only views this as a valid action if the component is currently in a state of 'Idle', in which case it can transition its state to 'Processing' and pass the action through to be picked up by the relevant reducers or effects. If a loadUnapprovedUsers action is received and the current state of the component is not 'Idle' then the action is dropped by the state machine as there is no valid transition for it.
In the case of the loadUnapprovedUsersError, if the component is in a state of 'Processing', the state will be transitioned to 'Idle', but no action will be passed through as no further processing of the action is required.
While this format for specifying component states worked, it quickly led to a lot of boiler plate in the components, and wasn't overly readable. In the next post I will look at how we abstracted this into a fluent builder class to construct the component states as a tidier alternative to object literals. In the fourth and final post I will explain how each of the pieces are wired together to make it all work in practice.
The next part of the puzzle was to provide a way for components to register the particular actions they were interested in, and how each action should transition the current state of the component. Initially this started with a javascript object literal:
In the above object declaration a userApproval component declares an interest in three actions, loadUnapprovedUsers, loadUnapprovedUsersSuccess, and loadUnapprovedUsersError.
In the case of loadUnapprovedUsers action, the component only views this as a valid action if the component is currently in a state of 'Idle', in which case it can transition its state to 'Processing' and pass the action through to be picked up by the relevant reducers or effects. If a loadUnapprovedUsers action is received and the current state of the component is not 'Idle' then the action is dropped by the state machine as there is no valid transition for it.
In the case of the loadUnapprovedUsersError, if the component is in a state of 'Processing', the state will be transitioned to 'Idle', but no action will be passed through as no further processing of the action is required.
While this format for specifying component states worked, it quickly led to a lot of boiler plate in the components, and wasn't overly readable. In the next post I will look at how we abstracted this into a fluent builder class to construct the component states as a tidier alternative to object literals. In the fourth and final post I will explain how each of the pieces are wired together to make it all work in practice.
Why didn't you write the following parts? I found it really interesting.
ReplyDeleteGreetings from Barcelona.
I got distracted with other projects and forgot all about this - check back in a week, will try and get it finished by then.
Delete@vgb - was hoping to have 4th and final post up before now, but been held up - should be up tomorrow some time hopefully
DeleteThis comment has been removed by the author.
ReplyDelete