1. 23
    Create Redux Middleware to Dispatch Actions with the Async ADT
    3m 38s

Create Redux Middleware to Dispatch Actions with the Async ADT

Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 4 years ago

We would like the ability to group a series of actions to be dispatched with single dispatching functions used as handlers in various parts of our game. The only issue with that, is that animations and other design elements in our game require us to provide some temporal space between each of those actions in the series being fired.

This is something we can achieve by reaching for the Async ADT provided by the crocks library. In order to allow for Asyncs in our Redux flow we are going to need to create some middleware that can identify when an Async is provided as an action, and then handle it appropriately .

Instructor: [00:00] Inside of our game component, we provide this map dispatch function, which includes the start function that dispatches an array of actions when called, starting with the start game action that generates and selects a collection of nine cards, followed by hide all cards that deselects and flips the cards.

[00:16] We finish with start turn to generate a hint for the player to guess, which we import in from our turn reducer. Currently, all three of these actions are fired, one right after the other, when the player clicks the start game button. Over in the Redux Devtools, we see that start turn was the last action fired.

[00:34] With a quick jump back to the hide all cards action, we see that this hint was populated by start turn while hide all cards removed the selected true from each card, which was added when start game fired, generating the cards with the selected attribute as we see in the actions div pane.

[00:51] Let's create some middleware that will give us the ability to control the time between each of these actions firing. In our middleware async file, as asynchronous code can be very volatile, we find this error action function that we can use to create an FSA in the case of an error occurring.

[01:07] Let's get to work by exporting as default from this file an async middleware function that plucks off the dispatch function from the store provided to us from Redux. Then return a binary curried function that first takes in a next continuation function followed by a given action.

[01:23] We'd like to check if this action is an instance of the crocks async type and handle it appropriately if it is. To perform this type check, we'll reach for the crocks' same type predicate function that compares a value to either a constructor or another value, returning true if they're the same type or false otherwise.

[01:41] We'll also bring in the crocks async constructor to have something to compare the action to.

[01:47] Downstairs, deep in the belly of our middleware function, we use is same type to compare the async constructor with the provided action. If it is an async instance, we know it's safe to call fork on the action. Fork takes two unary functions. The first will be run in the case of rejection, while the second is used if the async successfully resolves.

[02:07] To handle the unlikely case of a left or rejected instance, we'll build this simple composition by first bringing in the crocks compose helper function to build out a composition that provides the next function, the result of our action creator that takes in the rejection error as its payload.

[02:23] With this function, we can dispatch any errors that may occur. For the right or resolved, we just dispatch the provided action.

[02:31] If we don't have an async, we just pass it down the line with our continuation function. Now, we need to get this into our middleware chain, so over in our store file we need to pull it in from the async middleware file, then apply it to our middleware enhancer, allowing us to now handle dispatched async instances.

[02:49] Now, let's dispatch some sweet, sweet async actions by first pulling in the crocks async constructor into our game component in order to create some instances to dispatch.

[02:59] We want to delay the dispatching of the last two actions so we can reach for the resolve after async construction function, which takes a delay interval for the first argument and a value to resolve with as the second, which will be our actions in this case.

[03:13] For our intervals, we'll give the player five seconds to memorize the cards. To make sure that the flip animation has time to complete, we'll show the hint a little over half a second later.

[03:24] That's it. Now, when the player clicks start game, start game is fired, showing the cards in all their glory. Just five seconds later, our hide all cards action is dispatched, followed closely by our start turn, displaying the hint.

egghead
egghead
~ a minute ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today