React Redux Thunk TypeScript Tutorial - Introduction for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to this video on react redux and typescript this is the second installment in the react redux typescript video series and in particular this video will focus on the redux thunk configuration so we've already seen how we can lay out our folder structures using react redux and typescript now we're going to add the ability to perform asynchronous operations using the redux architecture so what i'll do to start off with is i'll just create a react app with the typescript template with the mpx create react app redux thunk template type script command and while that's loading i'll just take a look at the folder structure that we'll be dealing with and this is similar to the previous videos folder structure so we're going to have our index and that's going to contain our app component and we will wrap that in the store so this door is available to the entire application and we're going to keep the app component quite lean and we're going to assign the ui to a main page component and this is we'll have the um all the ui elements although in our case we'll just simply lay out the structure for that and then of course we can have our store and within our store we have a root store which sets up our store we're going to have a models folder for the interfaces for the entire application and in particular the actions of the entire application and then we're just going to have a simple to do which will focus on the redux thunk asynchronous structure here which is exactly the same structure as the previous redux videos structure you have the action and the reducer and the actions model for that action and of course the to-do model so now that's loaded let's just cd into our redux thunk folder here and actually i probably should have named this redux thunk dash typescript just because when we install the dependency it may complain that we have the same name so i'm just going to change that to redux stunt ts in the package.json and we can see our dependencies here anyway so since we got this file open might as well see that and we can just do the npm install redux react redux and redux dependencies here using node package manager and the only addition in this video compared to the last video is this redux thunk and now let us perform the asynchronous actions so we can install some dev dependencies here we can just get the redux logger for a nice logging in our console of the actions and the states that it's in and then we can just get some types relating to the react redux and redux logger packages for our type safety so i can just install those and if i open up the package.json file we can see as our core dependencies we have redux redux type script react redux and then all the other stuff relating to create react app and typescript template and if we go to our dev dependencies we have those types for the redux logger and react redux so now that we have our folder structure in mind and we have our dependencies and our application set up we can just go ahead and remove some of the boilerplate so we can remove this app.css file we can remove this test file here we can remove this logo svg and we could probably remove some other things but that's enough and let's allow that for the eslint and what we can do here is we can just remove the reference to logo and the css file and we can just simply return a if an empty div here and what i might do is i might actually make this a functional component so i'll just make this const app which is of the type react functional component which is the sort of es6 arrow syntax sort of function and rather than return a div here what i'll do is we'll wrap our application to return the main page so that's can be handled nicely there so we have this main page and of course we need to create this component so in the source folder we can create a file and we can say components and slash main page dot tsx so we create a file which is a shortcut which when you have the slash it just creates that nicely for us so i'm just going to make this a class based component so using the react snippets extension i can just say rcc and click on tab here now there would need to be a few adjustments but it gives us a nice boilerplate here and i'm just going to say main page here just for now so when we render that we can just simply import that from the components file and it's currently a default export but we will make this oh we'll keep it as a default export so that's okay so that means we can just import it directly like this and that's going to come from the components and the main page within the components so if i save this and i run an npm start we should just get a very simple main page text so we'll let that compile and then yes we get our main page text and i'll just press f12 to open our developer tools and it should be noted what we will be getting is we'll be using jsonplaceholder for our synchronous request we're just going to do a get request and get all this information although this structure and outline of react and redux don't give you the tools to be able to grow your application and do any of the asynchronous operations so okay so we've got our main page set up we need to create our store so we can wrap our application in the store um so let's just create a few files here and we have our summary here and we can see that we're going to have a store folder and that's going to have a root store file in it so we can just say in the source folder we can create a new file and we can create the store slash where we'll configure our store and that just created the folder and file for us of course we will need to come back to this root store because we need the actions and reducers set up for our to-do's but we can just simply also have a file within this store here for the models and there's an actions file within that model so that's that global applications of our entire store we're just going to have one but this will just sort of outlines the structure for if you were to grow your application using redux redux done so in our store here this is where we can have a models folder and we can have the actions in here and of course we're going to need to come back to this one as well so i'll just close those two for now and the package json as well so in our store we've got models and actions and then we've got our root store now we just need to have our to do so i'm going to create a folder here in store called to do and i'll just create a to-do action dot typescript file and i'll also create a to do reducer dot typescript file and there's also going to be a models for the to-do's so within that to-do's folder i can just create a new folder for the models there and then of course we're going to have our to-do interface and we're going to have our standard to do action so actions.ts so let's just start off and we'll just start off by creating our interfaces and models for our to-do's so for our to-do we can export the interface to do with a capital t and if we look at jsonplaceholder here we can see that we get a user id an id a title and a boolean if it's completed or not so we can just pretty much copy these values here and use this as a starting point of course we're going to have these quotes here so i'll just do control d and get rid of these and of course i need to change this to the type that it is so the user id is a number the id is also a number the title is going to be a string and this completed is going to be a boolean and i believe these should also be semicolons and this is a string so we have our to-do interface ready now we can start to create our actions interface so i'll close that to-do interface and in the actions i'll actually import that to do that we just exported and that's from within the same file within the same folder now the difference between redux and redux stunt in terms of defining the type script and performing the actions is that in the synchronous actions there's only one sort of action that can occur but in the asynchronous um you know there's three different states that the particular action could be in so you can request the information and then it can either come back as a success or a failure so we need to handle and define both of those cases and we start off by creating our types and this could be in its own file as well if the application grows even larger and you need it in multiple files for whatever reason but this is going to be quite self-contained in this example so i'm just going to create this constant variable of the type of action and i'm going to use the fetch underscore to do's underscore request all up in capital letters there and of course the type is going to correspond to that and we can do the same thing and we do this for fetching the to-do so if there's a success here so i can do success and likewise i can do the failure now what i might do here is because the interface for the to do's request success and failure they're all going to be um the same sort of structure is i might create a base structure so i can extend that and put a different type on the particular action that we're required here so i'm just going to start off with having this interface and you can call it whatever you like like to do base um i might just call it to do base oh i might call it to do a sync just to confirm that it's an asynchronous option and okay so what states are we going to have here obviously we're going to want our to-do's but before we get out to do's we need to make sure that they're loaded so we just need to have some sort of boolean response here to signify whether or not the to-do's are loaded or loading or failed and of course we're going to need our to-do's and that's going to be of the type to do array so an array of the to-do's and there can also be an error so we can just output a string error here and i'm going to extend this to do base and i'm just going to say for the interface fetch to do's request this is going to extend b to do a sync interface and we can give it a custom type so it's going to have all this sort of structure here but so has a loading to-do's error but it also is going to have a unique type which is just going to be the type of the fetch to do's request and i can copy this two more times and rather than fetch to do's request i can have fetch to do's success and i can copy the type there and i'll just preempt this by changing that to type failure and i can rename this particular interface fetch to do's failure with a r so now that we have our actions interfaces set up we can just go ahead and export that as a type so we have our to-do actions action type and we do this so we can in the reducer it could be any one of those cases so we need to return that particular case so we can just say it's either going to be a request which will result in either a success or a failure so we can have that like that and that pretty much wraps up our interfaces for our actions so now we can actually create our actions and i might start off by just importing a few things i'm going to need to import dispatch which is just to have the dispatch type from redux and i also want our app actions so to have our app actions we need to actually define our global actions and since we now have our actions in our interfaces set up we can go ahead and do that so i think i just closed that so i'll just reopen that but in our models in to do we had particular actions here and then we exported the to do action type so and i might actually call this like plural types because there's multiple types here so that means in our models in our global models we can actually import that so we can import the to do action types and that's going to come in from and we just need to go back a directory out of models into the to do folder and go into those models and get those model actions and we can then export a type here of app actions and this is just going to be equal to the to-do action types and of course once the application grows and there's more action types you can just chuck on a another action type here and that's how you can extend the application but we just need this to do action types as our app actions so that means when we come to our to do actions we can actually import the app actions as a type because we want to specify with typescript that we're what we're returning and click type safety across our application so we can get those in from models actions and of course we need to import the different types that we just created from the model's actions relative to to-do's so in particular these ones the fetch to do's request fetch to do success and finally the fetch to do's failure and these are just coming from the same area in the local to do's models and those particular actions we'll also want the to-do model from models as well but in the to do file there okay so we're going to start off by creating a request to do's function and we can export that so we can export the actually i don't think we need to export it yet because what we're going to do is we're going to uh bound that particular request and this will become clear when we create it so we'll create a function here called request to do's and this is going to return something of the type app actions and we can use this sort of parentheses around our object to return the object directly and we know that this is going to have the type fetch to do's request so we're just filling out the structure of our interfaces here we're going to have our loading and while we're requesting it it's loading so we can set that equal to true while it's loading however the to do's is going to be an empty array and the error well that isn't an area yet because it's still loading and haven't received a termination of a success or failure so okay so you can return that and very similarly we can copy this for receiving the to do's so we can call this receive to do's which means there was a success so the type is success and it will be no longer loading so that can be set to false this is going to need to take in some to-do's and we're going to see where we get this value from soon but it will actually take this to do and we're going to need to do something special to actually get it in this format but we will actually get the to-do's and that means that there was no error and then i can actually just copy this again and for the final case we can have something called invalid date to do's which will be of the type fetch to do's failure and loading will be set to false the to-do's will be an empty array but in the case of an error we can specify an error message and we can just say unable to fetch the to-do list so these are our base functions but we need to create and export something that's known as a bound function and that sort of helps us to be able to receive this to-do's value because obviously we haven't got the to-do's yet because we need to make the request before receiving the to-do's and then once you receive the to-do's then you can plug it into this function here so we can export a constant function and we can just call it bound request to do's equals and what we'll do here is we need to return a function a dispatch function which is specified using dispatch which is of the type dispatch of our particular app actions and then we need to actually call the dispatch method so dispatch on the particular method that we want to dispatch so obviously we want to dispatch this request to do's function when this is called and this is going to be called elsewhere in the application so we need to bind it so that's why i call it bound request to do's this allows us to access these redux thunk actions and trigger them elsewhere in our components so we need to dispatch that and we're returning a dispatch function so when it's been dispatched what we can do is we can actually return something else here and this is going to be our fetch request to jason placeholder so i'm going to copy this url here and it's just the to do's with the query limiting it to five so i can just call the fetch api and i'm going to use backticks here although it doesn't really matter because it's just going to be the url but you know for edits and stuff like that you want the backticks and use the template literal to specify which number you're on and then with the response what i can do here is say okay the response dot json to convert it into json format which is a promise itself so we're going to need to do another then and with that json that we've received the json of the to do's we can go ahead and dispatch our action receive to do's and we can receive the to-do so we make the requests we get our to-do's in the json format and then with that to do's in json format we receive those json formatted to do's that's where this variable comes in handy so we can populate our to-do's array with that is json that's been coming from jsonplaceholder so now that we have our action set up we can create our to do reducer so we need to import those action types once again and i might actually just copy these here so i can import these fetch to do requests but i'm also going to need the actual to do action itself because i could be returning any one of these types here in our reducer and of course i need the to do model so what i might do here is i might just create an interface and i'm just going to call this to do state which will represent a interface for this state of the to-do state which is just going to be the loading the boolean the to-do's of a to-do array type and the error which will be of the string type and of course because we're making a reducer we need a default state and i've defined that model so i could call it that to do state default state and the default state will be well nothing's happened so the loading is false the to do's is an empty array and the error will be nothing because nothing's happened okay so this is where we can actually create our reducer here so we can export as a constant variable the to-do reducer and we can take in the state which is going to be equal to the default state and a particular action so that particular action is going to be of the to do action types and i just need to return something of the to do state which is done by using a switch statement here and i'm just getting an error here because i need to specify the returns so what i'll do is in our switch statement for our pure function or our reducer we're going to type in the action type so whatever it is is it a request is it a success is it a failure and i'm going to assign a different case here and for the case that it is the fetch to do's request what we can do in that case is we can just simply return some sort of object here of this sort of format saying that loading is actually true but the to-do's is well we haven't received them yet and that should be to do's and of course there's no error so that's the first case here now okay so we're going to have two more cases here um oh okay sorry let's within the switch statement and we're going to have the success case and the failure case now in the success and failure cases these are going to be no longer loading the to do's error other to do's for the failure will be empty but the error is going to relate to the action.error which we just set unable to fetch to his list so oh and of course we need to handle the success case so we can just simply say whatever the action to do's we receive in this reducer that's what we can give to the to-do success case and finally we need a return statement here so i'm just going to have a default case here in case you know it's no longer requested or anything like that and that's just going to be our initial state or whatever the state is so we have our actions set up and we have our reducers set up so we can actually go back to these root store and sort of create our root store now so let's just do that and okay so how can we do that we're going to need a few imports here the first import we're going to need is create store combine reduces even though we only have one we're building this to grow and we want to be able to handle that ability to grow so from redux we're going to need funk and something known as thunk middleware and that's coming from redux and then we're going to need to import the create logger from redux logger and of course we're going to need our reducer so we need to import the to do reducer that we just created and that's going to come from the to do folder and the to do reducer and finally we're going to need to import our app actions and that's coming from the models folder the global actions so similar to how we've only got one action and one reducer um this is just this structure so we can grow so with the same structure you can easily add a whole new section like let's say you have another asynchronous or synchronous um thing in the store like to do you can just simply create this same structure here import it and add it as necessary and that is the entire structure for the application so okay so we have the app action so okay we can just sort of create our logger we create logger and if this has gone too fast through this video i really encourage you to watch the previous video because it really steps through um the react redux architecture and middleware and all the concepts behind this so what we can do is we can actually export a constant variable root reducer and this is going to call the combine reduces which itself just takes a comma separated list of the reducers that we want to include we have to do reducer in this case and we also want to um export the application state type because we're going to need that when we create our store and use it and this has a particular return type and it's going to be the type of the root reducer so everything in the root reducer can be the shape of it can be accessible so that is our entire application state and we're going to need that type script definition of that state when we use it so finally what we can do here is we can actually just go ahead and create our store and we can use the create store method and this is going to take in our application state and our app actions as the first parameter here it's also going to take two others and this is just sort of instantiating or initializing them as empty objects so nothing really to be concerned about there i'm actually doing some hardcore customization sort of stuff but what i can do here is i can have our root reducer in here and then we need to actually apply our middleware so we can apply our middleware and we've imported thumb so let's use thunk as and this is where we use the thank middleware type which is our application state and our app actions as types so it's very important that we use and import thunk before logger so logger should be last because we need to go through all of the middleware before we log it out and recall that the middleware's in between the actions and the reducer so it um it does something after an action's called and intercepts that and then does something so in this case we're intercepting the fact that we're dealing with asynchronous requests otherwise it wouldn't the action wouldn't be notified that it's asynchronous request it'll go straight in the reducer and nothing will happen because it will it'll just execute line by line and i won't wait for anything to happen so this middleware is doing something in between that action and we want to wait for that to happen before we log it out so we put this logger as the last parameter here and this is actually outside this is a different middleware so the comma separation needs to be there so we have something like this for our root store okay so we have our root store that's great now we need to use it so in our index file we can import two things we can import the provider functionality from the wrapper from react redux and we can also import the store from store slash root store now we can use this provider wrapper to wrap our application in with the provider tag and we can actually put app inside that and this provider it takes a store and that will be the store that we just created so our entire application state in the form of our reducers and the connections through the dispatching of actions so we've got our index set up here so if we open up our app file we pretty much this is we don't really want to touch the app file itself because we've designated all of everything to happen to this main page so really we want to open up the main page now so let's open that up uh where is that in the components here main page and this is where we're going to set up everything so one thing we need to do is so to connect our store to the main page and provide everything to our entire application we need to connect to it and to connect to it react redux provides us with this connect function here from react redux so we can actually um this is actually a higher order function so what i'll do is i'll take this export default off here because i can actually export default the main page but i need to connect and this connect function is going to take something known as map state to props and map dispatch to props and what these are um these are essentially um well it's it's making everything into a prop so the state of our application and the actions so we can use those and this actually returns our main page component in a function so a little strange but we'll go back and we'll actually create these and then hopefully that makes a little more sense so okay we're going to need a few things here so okay so we're going to need something from react redux okay so we got connect from react redux we're going to need something from redux called blind action creators and just bear with me there's a lot going on here so just follow along and then all come together so this buying action creators what this is doing is recall that we made our bind action or our bound request to do's and this is going to allow us to access this act like use dispatch this action from anywhere so we need to bind it to the particular area that we're working on it with and this is why we're starting to do this map state to props map dispatch to props sort of stuff so we can you know we can get that action that we're dispatching from anywhere and then we can map it to the main page and then all of those dispatch and all those actions will be sort of accessible to the main page and likewise with the global state so we can import something known as thunk dispatch which is a asynchronous way to dispatch actions and we can import that from redux thunk of course we're going to need our entire application state so we need to import that from the store that one directory and the root store and we also need our app actions from the store as well but in the models folder within the global actions then we need to import the interface from to do so we can get that from the store from to do from models and the to-do model um okay let's just say it's declared but never used we'll use that and of course we're going to need our action and our action is this asynchronous request for beyond request to do's which is going to dispatch another action here and i said an asynchronous action so we're using it's going to be of the type not dispatch but we're going to need that so we can access that and that's going to come from the store and it's going to come from to do and to do action so okay so i'm going this is going to be an empty interface and this just is here not because it has to be here in this case but just to demonstrate that if the app had its own properties you'd define them in here and they'll be combined with what the overall state and dispatch properties are going to be used in this main page so if this had any of its own props you could chuck it in there and you can also extend your own props if required now we don't have any of our own props so we're just going to say interface link state props and this is going to just be a model of the state of our application and this date of our application that we need to link is just simply the to-do's we just want access to the to-do's and we're going to have another interface here called link dispatch props and this is going to be the bound request to do's function and just the shape of that function is just it doesn't take anything and just returns void and most of these will just return void and we can create a type with the you know the props the link state props and the link dispatch props so i can create this type here called link props and it's going to be props and link state props and also the link dispatch props so we have this separation but then we join it together because in the map state to props we need to um sorry not in the map state to props but in the [Music] component the component needs to be aware of this so we can just pass in here as a type of the component it's referring to these link props so we still need to create map state to props and map dispatch to props so let's do that and we got the tools we need now to create that so let's start with map state to props and this is going to take in the application state so the state of the application or the app state and what it's going to return to us is something in the form of the link state props so we're taking the application state and we're sort of linking that application state to properties and the properties where we want accessible within this consumption of the store is this to-do's array here so we can just return the to-do's and that's going to be on the state and recall that the app state is nothing more than the um group store uh in particular the root reducer and the root reducer contains um all of the reducers but in our case we just have the to do reducer and we've referenced the to do reducer uh we're just returning the to-do um so that's that's all we really need to return here but to return the to-do's we need to access the to do reducer and on that root reducer you know we have our error we have our loading but alls we really want here is we want our to-do's so we can just return that so we have the map state to props hooked up that gets rid of that error so let's do a similar thing here for the map dispatch to props and this takes in dispatch as a function and this is of the type func dispatch with reference to the application state an empty object and a actions and this is going to return us the object of the particular type of the dispatched uh action so not the type sorry but the particular action that we're calling and the we already have this sort of down request to do's here so we can map that interface accordingly and this is where we need this bind action creators function from redux and that just allows us to tap into the actions that are created outside of this area sort of thing and we can down request okay so we can just bind those and what we do here is we just bind it to the particular action here and we that takes in as a second parameter dispatch so this is relating to this bound request to do's where you know we request the to-do's it dispatches an action or returns a function to dispatch that action that function that returns to dispatch to action um sort of this also induces this next return statement to call the api we're mapping the dispatch props by importing that particular action but because it's outside of this scope we need to bind it using this buy and action creators and likewise we have the application state and we just have our to-do's here and with these two functions here we can see that we can now connect to our store and our main page now has access to the entire state and all of the actions that have been specified so we've pretty much done all the hard work now all we need to really do is just use it so let's do that and okay so to do that i just want to actually now that we've linked the state to the properties that means this main page has this to do's as a property and likewise it has this down request to do's as a property oh as a prop sorry so we can actually just get that and we can use some destructuring here and we can get the to-do's by restructuring props what okay and okay so we're getting an error because it's declared but never used so let's use it and what i might return here um okay so okay this needs to be in the render function for one thing okay so but what we need to return here is we need to return a bunch of things so let's just keep everything in a div and let's just sort of line this out a bit nicer and we can just have like a header tag here we can just say to-do list and what we can do is we can have a ul and this ul needs to have a okay and obviously this div needs to be at the end here we need to loop through our list items that were received so before i do that we need to actually use a life cycle method because we're in the class based component system so in the main page i'm going to have this component did mount function and this is what is going to fire when the component did mount so the html has been rendered and we can just say this dot props dot bound request to do's because recall that we found both the actions and our state to properties of this main page so we can access this main page props and actually fire this bound request to do's that's been bound by using the spine action creators to link to the actions and returns its own dispatch functionality or function and then that gets connected to our store and then this is accessible through this page so we just want to do this when on the component did mount so the you know the dom's been painted essentially and we can make the request we can fire that off and then we can populate our dom with that data so we can do that in a ul and within that ul this is where we can we can tab that in for one thing but we can actually use some jsx here so for the um to do's that we've destructured from these props we can actually just map that and we're going to map each of the to-do of the to-do type so that should uh what's going on here can i find module store to do models to do store to do hmm okay i'm just gonna leave that for now and come back to that so i really wanted to finish off this logic here so [Music] this is going to be mapped to an li and each li i'm going to just say okay well it's going to have the key of the to do id which recall that in our to-do model we have an id a title and completed along with the user id being returned here so to uniquely identify that particular list element i can just do that with the key to do id i can then render in the ally the title and what i want to do is i just want to cross it out if it's completed and leave it open if it's not completed so on the loi i'm going to have a style and i can use the double curly braces here to indicate the object css object here so i'm just going to say okay we can have text decoration and if the to do is completed we just use this ternary here we can chuck the line through it otherwise if it's not completed we just have none here like that so let's just save that and we are still getting this error here okay so okay so we just got to go backward directory that's all it was to the store so if i save that okay again this error invalidate to do's is the sign but never read and that's true we never handled that case but this was more about the structure of the redux thunk so i'm sure you're able to handle that um but if we look into our react application okay so what's happening here we reload it and we fire an action we request the to-do's and that request to do's is coming from the main page and in particular when it's painted or the components mounted we call that that fetches them and it was a success because we get this action back now we're using redux thunk we can have access to this asynchronous behavior here and we get this success here which you know has its own state associated with it in particular we're interested in to do's and we've just mapped those out as um allies in our list and we've just have this one that's crossed out because if we look at our state we can see that this one is actually completed here so great so we've figured out how to use redux stunk and in the previous video we did regular redux so we now have the architecture needed to scale this application and manage our state efficiently so just to sort of recap everything that we've done here in this video we started by we creating a store in our index file and wrapping and providing that store to our entire application and the application or the app file just references this main page and this main page this is where we actually do the work of connecting to the store and we've defined our root store so we created our to do actions we created our to-do reducer to handle those particular actions and recall that we had three different cases for an asynchronous request so you request it you receive it or you get an error we've added the middleware into our store so we can handle the async and also log out things neatly in our console and of course we've done the interfaces and models for everything for type safety but now we created our reducer of the to-do reducer we essentially implemented the functionality so the ability to make the request and perform the asynchronous actions by connecting to the store with this higher order connect function and we're mapping the entire application state and the all its actions to properties of this so we can you know of course we have to define a few things here such as you know the state and the actions that we have so we want the to do state and the ability to request to do's we made that all into its own type and then we made the map state to props so we took the application state and we just mapped that to the property likewise with the dispatch prop we have this asynchronous dispatch function which is a function that returns a function and we bound that function for the down request to do is that we imported here and you know we can just fire that dispatch so able to do that and that means we have a way to sort of control the entire architecture and the entire properties and state of our application in a nice way and everything from here is just using the same principles and extending it pretty much and having extra sections and stuff like that so you make the request by calling the dispatching that action when the component mounted and then that will get populated and rendered into the dom and as a result you get the information and you get this nice asynchronous to-do list so thanks so much for watching and i'll see you in the next video i'll see you then
Info
Channel: Jon Peppinck
Views: 3,694
Rating: 4.9512196 out of 5
Keywords: react redux typescript tutorial, react redux typescript tutorial 2020, react redux typescript tutorial 2019, react redux typescript course, react redux typescript example, react-redux typescript example, react-redux typescript, react native redux typescript, react typescript redux project, react redux with typescript, react redux and typescript tutorial, redux typescript example, react redux typescript 2020, typescript react redux, redux-thunk, redux thunk, redux thunk typescript
Id: VOWVYpOy_Lw
Channel Id: undefined
Length: 63min 44sec (3824 seconds)
Published: Thu Aug 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.