1 00:00:02,110 --> 00:00:07,990 So now that we added storing, fetching, updating and deleting and therefore all the crud functionalities 2 00:00:07,990 --> 00:00:12,070 and we had a look at showing a loading spinner and handling errors, 3 00:00:12,070 --> 00:00:14,020 there are two things missing. 4 00:00:14,020 --> 00:00:20,560 One is that when we actually place an order, that we do send that order to a server too and that we 5 00:00:20,560 --> 00:00:22,900 store the order there as well and not just locally 6 00:00:22,900 --> 00:00:27,760 because right now of course when we order something we see it here but as soon as we reload the app 7 00:00:27,760 --> 00:00:30,650 since we're not storing it on a server, that is lost, 8 00:00:30,660 --> 00:00:32,160 so that's one thing. 9 00:00:32,170 --> 00:00:35,130 The other thing is of course that we only show a loading spinner here 10 00:00:35,200 --> 00:00:39,570 and we also only handle errors here. On the admin screen if something goes wrong, 11 00:00:39,610 --> 00:00:43,970 we get no error, also here if we edit this and we submit this, 12 00:00:44,080 --> 00:00:47,320 we see no loading spinner whilst we're waiting for this to be submitted. 13 00:00:47,320 --> 00:00:49,120 So that's also something we could improve 14 00:00:49,150 --> 00:00:51,310 and that's actually the part I want to start with. 15 00:00:52,210 --> 00:00:57,670 So here on the edit product screen when we dispatch updating or creating, in both cases this of course 16 00:00:57,670 --> 00:01:04,210 takes a while and indeed we get back a promise here because both in the update and create product action, 17 00:01:04,600 --> 00:01:10,270 we're using the Redux Thunk feature of returning an async dispatch function here which therefore returns 18 00:01:10,270 --> 00:01:15,340 a promise which therefore is returned as part of our dispatch function call here. 19 00:01:15,520 --> 00:01:20,680 So therefore we actually get the information, whether we're waiting for the response, whether we got an 20 00:01:20,710 --> 00:01:22,470 error or whether we're done, 21 00:01:22,630 --> 00:01:24,380 we just need to use it 22 00:01:24,520 --> 00:01:31,300 and of course we can use it in a similar way we did before, with use state imported from React and 23 00:01:31,300 --> 00:01:37,650 then by managing the loading and the error state here. Side note, you could of course also work with 24 00:01:37,650 --> 00:01:43,080 a reducer where you merge both states together if you wanted to with the help of the use reducer hook. 25 00:01:43,380 --> 00:01:43,650 Here 26 00:01:43,800 --> 00:01:52,750 however, I'll stick to isLoading and set isLoading and initially of course this is false and also have 27 00:01:52,750 --> 00:02:02,510 the error and set error variables here with use state like this, which initially is undefined 28 00:02:02,880 --> 00:02:07,470 and now we just need to set this as we're dispatching actions or as we're getting errors. 29 00:02:07,470 --> 00:02:13,530 So here when we're about to dispatch this, no matter if we're editing or if we're creating, I want to 30 00:02:13,530 --> 00:02:25,000 set isLoading to true and I also want to set my error here to false or not to false, to null, reset it. 31 00:02:25,190 --> 00:02:30,420 Now once we're done, I want to do something else but for that, we first of all need to wait for dispatching 32 00:02:30,420 --> 00:02:31,840 to be finished. 33 00:02:31,860 --> 00:02:37,350 Now we can therefore turn this into an async function again, just so that I can use to await keyword in 34 00:02:37,350 --> 00:02:37,770 there, 35 00:02:37,770 --> 00:02:44,720 the alternative would be to not turn this in an async function and simply add then and catch thereafter, 36 00:02:44,770 --> 00:02:45,810 that would work as well 37 00:02:45,810 --> 00:02:52,620 but I like to use async await. So now we can await for both dispatches to finish, of course only one 38 00:02:52,620 --> 00:02:57,230 of the two will run because that's an if condition but we can wait for that to finish and therefore 39 00:02:57,330 --> 00:03:00,380 after this if block, we know that will be done dispatching 40 00:03:00,370 --> 00:03:08,370 so here we can set isLoading back to false. So that's the loading state, now to handle errors, we just need 41 00:03:08,370 --> 00:03:15,420 to wrap this with a try catch block and we can actually wrap the entire if block here with try catch, 42 00:03:15,420 --> 00:03:23,250 so let's grab that, move it in here and then catch any potential errors we might be getting here and 43 00:03:23,250 --> 00:03:29,400 now here, I of course want to set my error to the error I'm getting here or to the error message I'm 44 00:03:29,400 --> 00:03:30,000 getting here 45 00:03:33,030 --> 00:03:39,720 Now we're setting the error, we're setting the loading state, of course this has no effect here on this 46 00:03:39,780 --> 00:03:50,380 screen. So to show a loading spinner, we need to import the activity indicator from React Native, activity 47 00:03:50,410 --> 00:03:54,120 indicator from React Native and to show an error, 48 00:03:54,130 --> 00:03:58,930 I also want to throw an alert and for that, you need to make sure that you're importing the alert which 49 00:03:58,930 --> 00:04:10,540 we're already doing. Now as a next step, to handle the loading state, maybe down there before I return 50 00:04:10,540 --> 00:04:19,930 my form, I will check if isLoading is true and if it is, I will return my view 51 00:04:19,930 --> 00:04:30,010 here with the activity indicator in there and there, I'll set the size to large and set the color 52 00:04:30,310 --> 00:04:38,980 to colors and for that, you need to make sure that you import that colors constant primary. So 53 00:04:38,980 --> 00:04:47,480 make sure you have that colors constant imported here, that's required and now I will also use the stylesheet 54 00:04:47,500 --> 00:04:55,120 here to add a new style, this centered style to be precise, here I will add centered and yes we could 55 00:04:55,120 --> 00:04:59,910 therefore also outsource this into a separate wrapping component if you wish to. 56 00:05:00,010 --> 00:05:08,300 There, I'll set flex to one, justify content to center and also align items to center, like this. 57 00:05:08,410 --> 00:05:15,250 Now we can apply this centered style here to the view which I wrap around my activity indicator by 58 00:05:15,250 --> 00:05:19,990 setting the style here to styles.centered. 59 00:05:20,040 --> 00:05:26,460 Now we should be seeing this whilst we're loading and on a side note, we also now shouldn't navigate back 60 00:05:26,460 --> 00:05:27,480 before we're done. 61 00:05:27,840 --> 00:05:33,700 So if I add or if I remove that exclamation mark and then leave that input so that this is submitted 62 00:05:33,700 --> 00:05:34,640 and I click save, 63 00:05:34,770 --> 00:05:38,400 you saw the loading spinner and we only navigate back after this is done. 64 00:05:38,400 --> 00:05:42,180 Now Firebase is super fast but still, that is what happened. 65 00:05:42,330 --> 00:05:52,970 Now to simulate an error, I'll go to the products actions and there in update product down here, I will 66 00:05:52,970 --> 00:05:58,310 remove that s here again to force an error and I will also add something else, 67 00:05:58,400 --> 00:06:03,130 I will now store the response here in a constant because now I actually do care, 68 00:06:03,200 --> 00:06:07,240 I want to make sure that if the response is not okay, 69 00:06:07,250 --> 00:06:14,360 so if we have a 400 or 500 status code, I also throw a new error where I say something went wrong or where 70 00:06:14,360 --> 00:06:20,200 you do whatever error handling you want to do, so that we also throw an error in that case. By the way 71 00:06:20,210 --> 00:06:25,620 I'll do the same for deleting before we test this forced error which I implemented. 72 00:06:25,670 --> 00:06:29,150 So here for deleting, I also want to check this and for that of course here, 73 00:06:29,360 --> 00:06:36,120 I also need to get my response by awaiting the fetching here. Okay with that, 74 00:06:36,120 --> 00:06:40,400 let's see if that forced error for updating due to dismissing s here, 75 00:06:40,470 --> 00:06:46,680 if that has an effect. If I now go back here to admin, I start adding this, I add an exclamation mark and 76 00:06:46,680 --> 00:06:48,010 click this, 77 00:06:48,030 --> 00:06:54,150 now what you'll see is that the update is simply dismissed, so we don't see the exclamation mark here 78 00:06:54,240 --> 00:07:00,230 but we also get no error message which makes sense because I have no logic to do that. 79 00:07:00,310 --> 00:07:01,700 Now how can we handle this? 80 00:07:01,720 --> 00:07:04,310 As I said, I want to throw an alert and therefore 81 00:07:04,330 --> 00:07:10,610 I will use use effect, so that use effect hook which React offers which we find here, 82 00:07:10,690 --> 00:07:16,690 I want to use that and I can simply implement that here 83 00:07:16,710 --> 00:07:24,490 after initializing the reducer let's say, exact position doesn't matter too much. Use effect here should 84 00:07:24,880 --> 00:07:28,670 rerun whenever error changes, 85 00:07:28,750 --> 00:07:34,510 so if we set this to be an error to not be an error, then here I check if error is true-ish, 86 00:07:34,510 --> 00:07:39,010 so if we have an error and if we do have this, then I can throw an alert, 87 00:07:39,010 --> 00:07:41,380 an error occurred. 88 00:07:41,380 --> 00:07:48,920 I want to output my error here and that should be the error message because that's what I'm setting 89 00:07:48,920 --> 00:07:49,350 here, 90 00:07:49,370 --> 00:07:55,270 I'm setting my error to the message so that should be a string which I can output and then I'll 91 00:07:55,270 --> 00:08:04,610 add a button where I say OK which simply dismisses this. Now also important, if we get an error, 92 00:08:04,610 --> 00:08:11,180 I don't want to navigate away. So to avoid that this happens, I want to make sure that here, this props, 93 00:08:11,210 --> 00:08:19,670 this navigation here actually only is performed if we don't end up in this catch block. 94 00:08:19,700 --> 00:08:27,390 So basically here after the if else block but still in the try block, there I want to navigate away. 95 00:08:27,410 --> 00:08:29,300 So now let's give this another try, 96 00:08:29,300 --> 00:08:30,710 let's go back here, 97 00:08:30,710 --> 00:08:33,920 edit this, add an exclamation mark, click somewhere else, click save 98 00:08:33,920 --> 00:08:40,730 and now I get my error message here and I stay on this page and it's also reset. I can add this again, 99 00:08:40,760 --> 00:08:43,430 click here and it's gone. 100 00:08:43,700 --> 00:08:50,150 On the other hand if we now fix that error here in the actions by readding that s here and we now go 101 00:08:50,150 --> 00:08:52,960 back and have another look at this, if 102 00:08:52,970 --> 00:08:57,170 I edit this, add my exclamation mark, click somewhere else and click save, 103 00:08:57,170 --> 00:08:59,880 now that all works as it should. 104 00:08:59,900 --> 00:09:04,200 So now this really works and now this behaves in the way it should behave. 105 00:09:04,220 --> 00:09:09,890 Now you can of course also add a loading spinner and an error handler here to the user product screen 106 00:09:09,890 --> 00:09:10,840 if you want to. 107 00:09:10,850 --> 00:09:15,800 So if you delete this which I won't do here but if you would delete this, you would currently not get 108 00:09:15,800 --> 00:09:17,300 a spinner, a loading spinner, 109 00:09:17,300 --> 00:09:22,610 you also won't get an error if it fails. To save some time, I'll not implement this here but you could 110 00:09:22,610 --> 00:09:26,590 implement it in basically the exact same way we did before if you wanted to. 111 00:09:26,600 --> 00:09:28,670 So that's something you can definitely also do.