 Hey everybody, what's up? It's Rob Dutson. Welcome back to the Polycast Show. So today, we're going to be talking about doing asynchronous actions using Polymer Redux. And to do this, we're going to use a little library called ReduxThunk. So ReduxThunk, kind of in a nutshell, basically teaches Redux to treat certain kinds of actions as functions. So I can give it a function and I'll run it as if it's any other action. And inside of that function, I can do all sorts of cool asynchronous work. And I can share those functions amongst my different components so that way I don't have to duplicate that work all over the place. So I'll teach you how to do that as well today. So follow me over here to my text editor. And the first thing we're going to do actually is bust open the terminal. And inside of our project, we're just going to npm install dash dash save ReduxThunk. Now I've already got PolymerRedux and I've got Redux installed from the previous episodes. So if you haven't seen that episode, definitely go check that out. We'll include a link to it, maybe a little picture in picture window will pop up somewhere. Go check out that episode. Over here, though, we're just going to install ReduxThunk from npm. I've already got it set up, so we're good to go. The next thing I'm going to do is go over to my text editor. And here, I'll bump this up a little bit to make it a bit easier to read. And I'm going to start off by creating a ReduxStore. So here, I am importing PolymerRedux. And then I've got a script element inside of this HTML import called ReduxStore. And the first thing I usually do is create some initial state. So I'll say cost initial state. And what we're going to build today is a really, really, really simple example. It's just going to be a little form that someone can type in a username and click sign up. And then it's going to go off and do a little bit of asynchronous work. And when that work is done, it'll display that person's name. So while it's doing the work, it'll be loading. And then once they're done, it'll be like, welcome. So when so, you know whatever username they put in. So our initial state here, we'll say loading is false. And we will say, we'll give it a name. That's good. Initial state, say loading is false. And username equals null. Cool. So once I have my initial state in place, the next thing I want to do is write a reducer. So reducer is going to take in the actions that are just batched and modify our state. So we'll say reducer is a function that takes state and action as arguments. We'll say, hey, if there was no state passed in, then we will return our initial state. Otherwise, we're going to switch on the action type. So we'll switch action.type. So the first action that we'll be looking for is sign up started. We're going to just return our state object. And as is sort of like the typical redux pattern, we're going to make a clone of that state object. And we're going to mutate the loading flag inside of there. So we'll say return object to sign. And we'll pass in an empty object. We'll pass in our state to copy it over into that empty object. And then we'll pass in loading true. So someone says sign up started. We're just going to display a loading message. The other thing we're going to do here is we'll have sign up completed. We're going to do something very similar. We're going to return object.assign, pass in empty object, pass in state. And then the two things we're going to do here is we're going to set loading back to false. And we're also going to assume that someone is going to pass in the username as part of that action. So we're going to say username is equal to action.username. So this is our very simple reducer, just handling a couple of sort of asynchronous states. Once we have that in place, we need to create our store. Do it this way so I don't make a typo. There we go. So store equals redux create store. We're going to pass at the reducer. And then we're going to call redux apply middleware and give it this redux thunk thing. And again, redux thunk is going to teach our store and our dispatcher to take a function in certain cases and treat it as if it is an action. So you can still dispatch regular actions just like we did in the previous episode. We can also dispatch function now or give it to the dispatcher. And we'll run that function. And it will actually sort of treat it like its own action. But that way, we can do a bunch of async work inside of that function. So we're going to create our store that way. We're going to create a redux behavior. So we'll say const redux behavior equals polymer redux. We'll pass it the store. And then I want to create another behavior that's going to contain my asynchronous actions. So in the last episode, one of the things I did was actually kind of like hard-coded the action dispatch to the component that I was working with. And the issue with that is if you have more than one component that needs to dispatch the same action, that would be sort of annoying and repetitive to have to implement that in every single component. So what we can do is we can create a behavior for the actions object that polymer redux uses. And we can share that amongst any sort of components that want to dispatch these particular actions. So I'm going to create a new behavior called async actions behavior. This is just going to be an object. It is going to have an actions object on it. And the action that we're going to be doing is just going to be called sign up with timeout. So we're not actually going to go talk to an API or anything to simulate an asynchronous action. I'm just going to write a set timeout inside of this action creator. So our action will be sign up with timeout. It's a function that is going to take as an argument a username. And it's going to return a function that takes a dispatcher. As an argument, so that's going to be the actual redux dispatcher. Basically, redux thunk is going to handle passing that dispatcher into this return function for us. And then we just want to dispatch a few actions. So the first thing we'll do is we'll call dispatcher.dispatch. Let's see. Let me make sure I didn't do this. Let me make sure I did this right here really quick. So we're passing in dispatch. Oh, this is what I got wrong. I knew I was doing something wrong. Instead of passing in the dispatcher object, we're just passing in the dispatch method. So we don't actually have to say dispatcher.dispatch. We just say dispatch. And the first thing we'll do is we'll dispatch an action whose type is signed up started. So this is going to kick off our asynchronous process. Then we're going to do a set timeout. So set timeout, give it a function here. Say wait maybe like 3,000 seconds. And then inside of this function, we're going to dispatch another action this time. We'll assume that our asynchronous sign up process is completed, our server responded, or whatever. So we'll say sign up completed. And then we're going to say username is equal to this username value that was passed in here. So username is equal to username. OK, I think that looks about right to me. So what we're going to be able to do now is share this behavior amongst components. And then those components can just say this.dispatch sign up with timeout. And they can pass in a username value. And then it'll go do all this asynchronous work or whatever. And then eventually that will update our state. So let's actually go implement that. I'm going to create a little sign up form component. So I've got a signupform.html that I've created here. I'm already importing Polymer. I'm already importing our Redux Store. So I will just stub out Polymer element called signupform. Inside of here, we're going to have a label for our username field. So let's see input. That equals text. So it'll say username. Fill that in there. And then we'll have a button where we say sign up. And whenever someone taps this button, we will call our sign up function. And down here, we're going to implement that sign up function. And this will be pretty straightforward. We're just going to say, so let username equal. Let's see. Let's give this input text an ID. So we'll say ID user or something. So we'll say username equals this $user.value. And then we'll say this.dispatch sign up with timeout. And we'll pass in that username. Now we need to also make sure that we are mixing in the correct behaviors for this element. So we empower it with cool Redux abilities. So we'll say behaviors. I'm so going to spell this like wrong. There we go. OK, behaviors. We want to make sure that we put in the Redux behavior. I think it's just called Redux behavior. Let's check our store really quick. Redux behavior and async actions behavior. I'm going to copy both of these so that I don't make any typos here. So we'll drop that in. We'll say I want Redux behavior. Let's say I want async actions behavior. So now what this has done is, if you watch the previous episode, we actually gave our action dispatching element an actions object, like a properties object. In this case, though, we're just sharing that because we've got that async actions behavior. And we've already sort of defined the actions object there. So that's just going to get shared with this component. So it can just call dispatch. It can reference this, sign up with timeout, action creator, and then it'll do all this work for us. So I think that this looks good so far. Now, the next thing I want to do is I want to create another element to just sort of like display the state as it's being updated inside of our app. So I'm going to create another element just called notification bar. So it's notification bar.html. Just like the last one, we're going to import Polymer. We're going to import the Redux store. Let's start to stub this one out. So we'll say notification bar. This one is actually going to have some properties. So properties. And these are going to be coming from our Redux store. So the first property is going to just be loading type boolean. And then remember from the last episode, the way that we reference something in the Redux store is we'll use this state path property. So state path, in this case, because it's like right on the root store object, we can just say the state path is loading. But again, if it was nested, if it was at foo.bar.loading, we could reference it this way using dots. But we're just going to say loading. And we're also going to say the username is going to be passed in. So that is just going to be a string. And again, the state path for that will just be username right on the root object there. And so I'm just going to do this quick and dirty. I'm not going to do a bunch of elaborate checks or guards or anything about things being undefined or whatnot. I just want to demonstrate how this works. So I'm going to write two templates, one that displays a loading message and one that displays the username, just assuming that everything works and is fine and dandy. If it doesn't, though, inside of sign up form, for instance, you could have, or sorry, inside of this isn't actions behavior here. Sign up with timeout. You could have error handling inside of here. You could dispatch an error state action or something like that as well. This is where you would do that work. But in our case, we're just going to keep it pretty simple. I'm going to make a couple DOMIF templates. So let's say template is DOMIF. If we are loading, then we're just going to have a little paragraph. Whoa, that is way more than a paragraph. We'll just have a little paragraph there. There we go. That says loading dot dot dot. And then we'll drop in another template is DOMIF. If we have a username, drop in another paragraph. And we'll just say, welcome username, like that. So again, I'm not doing a bunch of fancy error checking or anything like that. But I just want to demonstrate how this thing works. Let's go back to our index file. We're going to uncomment these elements. We're going to make sure notification bar is in. We're going to make sure signup form is in. We'll make sure we've got both of them down in the body. And then note here in my script tags what I'm doing. I'm pulling in Web Components Lite.js. I'm pulling in Redux. And I'm pulling in Redux Thunk. Remember to pull this in as well. Don't wire all of this up and then be like, why the heck isn't it working? So make sure you pull in Redux Thunk as well. And now I think we've got everything set up. Let's go over here. Refresh the page. I'll zoom this in so you can see it. So I'll open the console in case something explodes. That's always good to see if that happens. So what we want to happen is someone's going to type in their username. They're going to click Sign Up. It'll put the app in a loading state. And then for three seconds, because we got that set time out in there, it'll just say Loading. And then eventually it'll come back and it'll say Welcome and whatever username we type. So we'll say put in Bob Dodd. Bob Dodd, there we go. Sign up. And nothing happens. It's totally broken. Where did we go wrong? All right. Oh, let's see. So this Dodd dispatch, sign up with time out username. So let's just make sure that this is even being called. So we'll log username. Make sure that's being called. So Bob, sign up. OK, that part's working. Let's make sure in our Redux Store actions, sign up with time out. Oh, oh, oh. I knew it. So our notification bar here, I totally forgot to mix in the behaviors. So I always do this. So I want to pull in this Redux behavior. It does not need the async actions behavior because it's not just batching any actions. It's just going to be displaying whatever we type in. Let's try this again. So we'll say Bob Dodd. Say sign up. It says Loading. Tick, tick, tick, tick, tick. Boom. Welcome to Bob Dodd. All right, so there you have it. That is a very easy way to add asynchronous actions to your Redux Polymer app. I'll include some links down in the show note for some more information on Redux Thunk because it's cool, but it's also another big topic that is kind of outside of the scope for us to explain in the show. But I'll definitely give you some reading material so you can learn more about it. As always, if you have questions, you can leave them for me down in the comments or hit me up on a social network of your choosing at hashtag Ask Polymer. As always, thank you so much for watching. I'll see you next time. Hey, folks, what's up? It is Rob. Thank you so much for watching this episode. If you'd like to see some more, we got some over there in the playlist. And as always, you can click the little Subscribe button to keep getting content every time we push it up to the channel. Again, thank you so much for watching.