1 00:00:02,060 --> 00:00:07,190 So in the create product action creator which currently is a function that just returns an action, 2 00:00:07,550 --> 00:00:12,560 we can now tweak this a little bit. Instead of returning an action, we can now return another function 3 00:00:12,560 --> 00:00:13,050 in there 4 00:00:13,070 --> 00:00:18,890 thanks to Redux Thunk, thanks to this package we can do this now and this will be a function which receives 5 00:00:18,890 --> 00:00:29,650 the dispatch function as an argument and then in turn needs to dispatch an action. So in here, in this 6 00:00:29,650 --> 00:00:31,100 return function, 7 00:00:31,180 --> 00:00:36,310 I now simply need to not return this but dispatch this action, 8 00:00:36,310 --> 00:00:42,090 that's the important difference and I'm missing a curly brace here. 9 00:00:42,130 --> 00:00:43,110 So what happened? 10 00:00:43,360 --> 00:00:50,230 I change create product to be a function which we actually still can dispatch from inside our components 11 00:00:50,740 --> 00:00:53,500 but which now can still work as before, 12 00:00:53,530 --> 00:00:58,870 so we don't need to change all these action creators, so you can stick to the old syntax but now thanks 13 00:00:58,870 --> 00:01:03,770 to Redux Thunk, an alternative syntax so to say is also supported 14 00:01:03,970 --> 00:01:10,180 where this action creator function does not immediately return an action object but instead, where it 15 00:01:10,180 --> 00:01:15,970 returns a function and if it does, Redux Thunk will step in and make sure that everything still works 16 00:01:16,510 --> 00:01:22,180 and if it returns a function, then this is a function which has to receive an argument, the dispatch function 17 00:01:22,390 --> 00:01:28,390 which will be passed in automatically by Redux Thunk, so Redux Thunk will in the end call this function 18 00:01:28,390 --> 00:01:28,900 for you 19 00:01:29,620 --> 00:01:35,560 and then therefore you can then dispatch a new action and here, dispatch the actual action object which 20 00:01:35,560 --> 00:01:39,680 we previously wanted to dispatch but before you do that, 21 00:01:39,850 --> 00:01:47,170 you can now execute any async code you want and that will be allowed and will not break your Redux flow 22 00:01:47,200 --> 00:01:52,240 because Redux Thunk will take care about this and you can learn more about this in my React Course for 23 00:01:52,240 --> 00:01:56,020 example or of course in the official Redux Thunk documentation, 24 00:01:56,110 --> 00:02:00,340 also in the official Redux docs actually. 25 00:02:00,350 --> 00:02:05,900 So now here we can send a HTTP request and in React Native, we can use the fetch API which is 26 00:02:05,900 --> 00:02:08,120 built-in and fetch here 27 00:02:08,120 --> 00:02:12,590 works basically like the fetch API in the browser where this also is available. 28 00:02:12,590 --> 00:02:17,210 It takes a URL you want to send the request to and that's this URL we got here, 29 00:02:17,210 --> 00:02:21,180 so I'll just copy that URL from Firebase and enter it here. 30 00:02:21,380 --> 00:02:24,440 Now fetch sounds like it always just fetches data, 31 00:02:24,440 --> 00:02:30,440 so if it gets data but actually the name is a bit confusing here, it's not just used for getting data, 32 00:02:30,440 --> 00:02:33,950 you can also use it to send a post request or a put request, 33 00:02:34,040 --> 00:02:40,640 so any kind of HTTP request. Now also we don't just send a request to this URL but now as I 34 00:02:40,640 --> 00:02:47,930 said, Firebase translates your requests to kind of a database query and a database structure, so you 35 00:02:47,930 --> 00:02:50,990 can add any node you want here, any segment you want, 36 00:02:50,990 --> 00:02:57,230 like for example products and Firebase will kind of create a folder here in the database and store your 37 00:02:57,230 --> 00:02:58,410 data in there. 38 00:02:58,700 --> 00:03:03,800 Important and that's just a Firebase specific thing, you need to add .json here. 39 00:03:03,830 --> 00:03:11,140 So that's not required because of React Native or because of Javascript or because it's HTTP request, this 40 00:03:11,140 --> 00:03:15,690 is just a Firebase specific thing. By default, 41 00:03:15,700 --> 00:03:21,280 this would send a get request but to store data Firebase wants a post request and to send that, we have 42 00:03:21,280 --> 00:03:27,610 to pass a second argument to fetch which should be a Javascript object. In that second argument, 43 00:03:27,610 --> 00:03:34,480 you can set up the method key and describe the HTTP method of this request and that can be get, 44 00:03:34,480 --> 00:03:42,070 put and so on and here it should be post which adds this product we're about to send to this node which 45 00:03:42,070 --> 00:03:44,130 will be created there. 46 00:03:44,140 --> 00:03:47,760 Now you also can set up some headers there and we need to set a header, 47 00:03:47,920 --> 00:03:53,530 we need to add the content type header and you simply add headers as an object and then have key-value 48 00:03:53,530 --> 00:03:58,950 pairs with your header identifiers as keys and the values as values 49 00:03:59,200 --> 00:04:04,290 and here the value is application/json to let Firebase know that we're about to send some JSON 50 00:04:04,360 --> 00:04:06,530 data and then we need to do that. 51 00:04:06,580 --> 00:04:11,680 We need to add a body with the data we want to append to this request and the data should be in the JSON 52 00:04:11,680 --> 00:04:12,730 format. 53 00:04:12,730 --> 00:04:19,240 Thankfully, React Native supports the JSON object which browser-side Javascript also supports and there 54 00:04:19,240 --> 00:04:26,440 we can call stringify to turn a Javascript array or object into JSON format, so into a string in the 55 00:04:26,440 --> 00:04:28,040 end and there, 56 00:04:28,040 --> 00:04:33,210 I want to append my product. So in the end, I want to stringify 57 00:04:33,210 --> 00:04:37,420 an object here which holds my title, my description, 58 00:04:39,100 --> 00:04:42,100 my imageUrl and my price, 59 00:04:42,100 --> 00:04:47,830 not the ID because actually Firebase will generate an ID for us here which is really convenient. 60 00:04:49,070 --> 00:04:49,370 Now 61 00:04:49,410 --> 00:04:54,610 this will send the request but of course I only want to create the product locally if that request succeeded 62 00:04:54,820 --> 00:05:00,490 because then I can actually also use that automatically created ID which Firebase will return to 63 00:05:00,490 --> 00:05:08,410 me and fetch conveniently returns a promise, which is this Javascript object that will eventually resolve 64 00:05:08,410 --> 00:05:12,620 to a value in the future or throw an error in the future. 65 00:05:12,940 --> 00:05:19,290 So to wait for this response, we can then add then here after fetch, 66 00:05:19,290 --> 00:05:26,170 so on this promise and we'll get our response here so that we can do anything with the response. 67 00:05:26,190 --> 00:05:31,200 You can also listen to the errors with catch and that's something you should actually already know because 68 00:05:31,200 --> 00:05:33,290 promises are not React Native specific, 69 00:05:33,300 --> 00:05:39,900 that's vanilla Javascript and React Native also supports the more modern async await syntax instead 70 00:05:39,900 --> 00:05:46,270 of then and catch. To use that, you add async here in front of your function, 71 00:05:46,290 --> 00:05:53,700 this async keyword and now you can await your response here and store it in a constant with this syntax, 72 00:05:53,700 --> 00:05:55,400 with the await keyword. 73 00:05:55,410 --> 00:05:59,520 Now behind the scenes, this transforms this to the old syntax with then, 74 00:05:59,580 --> 00:06:05,640 so this is like if you added then here and you used your response in a callback you got there. 75 00:06:05,640 --> 00:06:09,480 But this is a bit easier to read which is why I will use this async await syntax, 76 00:06:09,480 --> 00:06:17,160 just be aware of the fact that this is like adding then, just more readable. When you use async await 77 00:06:17,160 --> 00:06:22,770 by the way, this function here always will automatically return a promise, therefore this entire create 78 00:06:22,770 --> 00:06:23,780 product function 79 00:06:23,820 --> 00:06:25,880 now returns a promise. 80 00:06:26,010 --> 00:06:27,330 It didn't do that before, 81 00:06:27,330 --> 00:06:28,300 now it will, 82 00:06:28,350 --> 00:06:33,040 you see that here, it now returns a promise. So that's our response, 83 00:06:34,280 --> 00:06:38,960 this response now can be kind of unpacked to get the data in there, 84 00:06:39,140 --> 00:06:45,430 so the response data, that's done by calling response.json, that's a method which is available 85 00:06:45,430 --> 00:06:50,730 on that response object we're getting. This again is an async task which we have to await for 86 00:06:51,050 --> 00:06:56,910 and now this will in the end give us the data returned by Firebase when we add a product. 87 00:06:56,920 --> 00:07:03,620 Now we can for now simply log that response data to see what's in there and I still dispatch my action 88 00:07:03,620 --> 00:07:03,790 here 89 00:07:03,800 --> 00:07:09,320 but since we have await here and therefore this is like it was in multiple then blocks, this will only 90 00:07:09,320 --> 00:07:13,520 be dispatched once these operations here are done. 91 00:07:13,520 --> 00:07:19,190 So with that, let's save this and let's add a new product by going to the admin section here and then 92 00:07:19,190 --> 00:07:21,580 I'll add a white shirt, 93 00:07:21,830 --> 00:07:24,820 I picked a nice imageUrl for that, 94 00:07:24,820 --> 00:07:26,320 here it is. 95 00:07:26,320 --> 00:07:34,510 Let's say that costs 39.99, this is a white shirt which is pretty stylish. 96 00:07:34,510 --> 00:07:39,110 If I now save this, need to load this first, 97 00:07:39,110 --> 00:07:40,130 now this is added, 98 00:07:40,130 --> 00:07:41,130 here it is 99 00:07:41,210 --> 00:07:46,310 and now if you have a look at Firebase, we also see that there now is a products node. In there, 100 00:07:46,310 --> 00:07:50,430 this is this unique ID and in there we have the data we submitted 101 00:07:50,620 --> 00:07:53,440 and if you have a look at your console, you see this is what we got back, 102 00:07:53,440 --> 00:07:55,100 that's this response data here. 103 00:07:55,120 --> 00:08:01,780 This holds a name key and then also holds this ID which Firebase generated, 104 00:08:01,780 --> 00:08:08,670 this means that when we dispatch our data here, we can actually add an ID key here and add resData.name 105 00:08:08,720 --> 00:08:14,800 to access this name key on the response return by Firebase to forward the server-side generated 106 00:08:14,800 --> 00:08:21,330 ID to our create product reducer in the end or to the logic that runs in the reducer. 107 00:08:21,340 --> 00:08:28,960 So now in the products reducer, we can actually not use this dummy ID here but instead, expect that 108 00:08:28,960 --> 00:08:36,530 on our product data. There we now get an ID field which is the server-side generated ID, I will stick 109 00:08:36,530 --> 00:08:43,430 to the dummy user ID for now though but we'll get this server-side generated ID here and here it 110 00:08:43,430 --> 00:08:48,910 is and therefore, we use this on the frontend as well which will be important for later when we also 111 00:08:48,920 --> 00:08:50,600 delete stuff and so on. 112 00:08:50,630 --> 00:08:55,460 So this adds a product but of course as soon as we reload the app, it's gone because in the app, it was 113 00:08:55,460 --> 00:08:56,810 only stored in memory. 114 00:08:56,810 --> 00:09:01,190 Now we also store it on a server but we're never fetching it from a server, 115 00:09:01,220 --> 00:09:03,170 so let's make sure we do that as well.