1 00:00:02,370 --> 00:00:07,800 Now we're really close to the end of this module therefore, we need to make sure that we now dispatch 2 00:00:07,800 --> 00:00:11,370 actions for creating a new product or for updating a product 3 00:00:11,410 --> 00:00:16,080 and therefore first of all we need to add these actions here in our actions folder. 4 00:00:16,210 --> 00:00:28,830 So I'll export a constant here, create product like this here, create product and then here also, another identifier 5 00:00:28,860 --> 00:00:38,500 for updating in product with update product and update product like this and create fitting action 6 00:00:38,500 --> 00:00:47,670 creators or create product and now it's up to you how you want to structure this, what data you expect 7 00:00:47,670 --> 00:00:50,270 to get when you create a product. 8 00:00:50,340 --> 00:00:56,370 I'm a fan of creating the product really here in the action or in the reducer, 9 00:00:56,490 --> 00:01:04,590 so I actually expect to get a title here, a description, an imageUrl and a price let's say and then 10 00:01:04,590 --> 00:01:14,070 I return an action object where the type is create product and the product data is simply all that data 11 00:01:14,070 --> 00:01:15,220 merged together. 12 00:01:15,450 --> 00:01:22,710 So here I have my title which is mapped to the title we get as an argument, description mapped to description 13 00:01:23,340 --> 00:01:28,230 and therefore we can also use a modern Javascript shortcut where if the property name and the value variable 14 00:01:28,230 --> 00:01:31,490 name is the same, you can just write it like this, 15 00:01:31,530 --> 00:01:36,810 so if it's the same like price: price, we can just write this here, of course that's also possible 16 00:01:36,810 --> 00:01:38,610 for title and description 17 00:01:38,610 --> 00:01:45,880 so that we map all these arguments into properties of the same name in this object and if we update a 18 00:01:45,880 --> 00:01:54,460 product that's relatively equal, update product, so we can generally copy that but there is one important 19 00:01:54,460 --> 00:01:59,920 difference. Here we also need the ID of the product which needs to change, so we get this as an extra 20 00:01:59,920 --> 00:02:08,370 argument and we can store this in our action therefore in a separate property of our action object. Now in 21 00:02:08,370 --> 00:02:09,510 the reducer, 22 00:02:09,510 --> 00:02:10,920 we of course need to handle that, 23 00:02:10,920 --> 00:02:20,900 we need to handle the creation and updating. So let's add a new case here in the products reducer for 24 00:02:20,930 --> 00:02:28,940 create product and for that, make sure you import create product from actions products and of course one 25 00:02:28,940 --> 00:02:33,740 for updating a product with update product, make sure you import that as well. 26 00:02:35,970 --> 00:02:42,300 In create product, of course we need to create a new product and I'll store it in a constant here with 27 00:02:42,300 --> 00:02:45,230 the new keyword in the product model we created earlier, 28 00:02:45,230 --> 00:02:51,780 for that you just need to make sure you import this product model here from the models folder and that 29 00:02:51,780 --> 00:02:58,260 product here receives an ID which for now can generate manually with new date to string to have a 30 00:02:58,260 --> 00:03:04,350 kind of pseudo unique dummy ID for the moment later, this will be generated on a server but we don't 31 00:03:04,350 --> 00:03:05,600 have that yet. 32 00:03:05,970 --> 00:03:11,580 Owner ID for now is hardcoded to U1 because we have no users in this app right now 33 00:03:11,580 --> 00:03:17,910 but title and so on can be populated with data from the action because in the action for creating a product, 34 00:03:17,940 --> 00:03:22,040 we have the product data key and that holds an object with title, description, 35 00:03:22,050 --> 00:03:24,010 imageUrl and price and that's data 36 00:03:24,010 --> 00:03:25,800 we can now retrieve. 37 00:03:25,980 --> 00:03:36,000 So here for title, we get action productData.title, for the imageUrl, it's action.product 38 00:03:36,360 --> 00:03:43,800 data.imageUrl, unsurprisingly for the description, it's action.productData.description 39 00:03:44,380 --> 00:03:52,780 and for the price, it's action.productData.price. This is now a new product I create. 40 00:03:53,070 --> 00:03:58,890 Now we need to add it to our store by returning our updated state here, where I first of all copy the 41 00:03:58,890 --> 00:04:03,840 existing state and now I need to add it to both the available products and the user products because 42 00:04:03,840 --> 00:04:09,690 we created it, it certainly therefore belongs to us, so it needs to be part of both arrays and the available 43 00:04:09,690 --> 00:04:15,480 products, well there we can take these available products we got and use concat to get a new 44 00:04:15,480 --> 00:04:21,990 array which is the old array plus add new element and here, new product is that new element and I do 45 00:04:21,990 --> 00:04:25,040 the exact same thing here for user products. 46 00:04:25,110 --> 00:04:34,220 So here I use state user products and I concat my new product. Now what about updating? For updating, 47 00:04:34,220 --> 00:04:37,430 we first of all need to find the index of the current product, 48 00:04:37,430 --> 00:04:46,580 so product index could be a constant name can be found by accessing our user products and there with 49 00:04:46,580 --> 00:04:51,570 find index which is a built-in Javascript method, we can find the index of a certain element. 50 00:04:51,590 --> 00:04:57,440 Again this takes a function which executes on every element in that array and that needs to return true 51 00:04:57,440 --> 00:05:02,930 so that we have an index and there I will look at the IDs and look for the IDs where it's equal 52 00:05:02,930 --> 00:05:05,330 to my pid, my action pid 53 00:05:05,330 --> 00:05:11,520 because if you remember how we set up that action, for updating we do have the pid field here which 54 00:05:11,520 --> 00:05:13,980 holds the product IDs we're getting. 55 00:05:13,980 --> 00:05:19,470 So I'm looking for that product and then I store the index of that product in the user products array 56 00:05:19,620 --> 00:05:21,890 in the product index here, 57 00:05:21,900 --> 00:05:27,720 now we can create an updated product here which is technically a new product object but of course 58 00:05:27,720 --> 00:05:29,570 prepopulated with some old data, 59 00:05:29,670 --> 00:05:31,200 for example we keep the ID, 60 00:05:31,230 --> 00:05:34,320 so we take action pid as a value here. 61 00:05:34,320 --> 00:05:40,080 I also keep the owner ID and for that, I can access state user products for the index 62 00:05:40,080 --> 00:05:46,070 we just find out, so for that product index, .ownerID, I won't change this. 63 00:05:46,290 --> 00:05:48,800 Of course I will store the new title, 64 00:05:48,900 --> 00:05:59,430 so here I will store action.productData.title, I will store the new imageUrl, so action.product 65 00:05:59,430 --> 00:06:03,180 data.imageUrl and I will store a new 66 00:06:03,180 --> 00:06:11,190 description, so action.productData.description. However I mentioned the price should not be editable, 67 00:06:11,520 --> 00:06:18,900 so as a value for this, I will keep the original price, so state user products product index.price 68 00:06:18,900 --> 00:06:24,750 here. By the way that also means that our action is not entirely correct, there 69 00:06:24,840 --> 00:06:30,150 I also expect a price, I shouldn't do that because we can't enter it in our inputs anyways, we don't 70 00:06:30,150 --> 00:06:36,060 need it so we shouldn't expect it here, we shouldn't forward it as part of product data for update product, 71 00:06:36,390 --> 00:06:41,090 for a new product we need it but for updating, we don't. 72 00:06:41,500 --> 00:06:46,600 So with that, we have our updated product with some new data and some old data, now we need to update 73 00:06:46,600 --> 00:06:55,090 our state of course and for that, we have the updated user products where in the end I copy my existing 74 00:06:55,210 --> 00:07:01,960 user products with this syntax here to create a copy and then I set updated user products for the selected 75 00:07:01,960 --> 00:07:09,460 product index equal to the updated product, so I replace the product at this index with the new updated 76 00:07:09,460 --> 00:07:15,790 product in my copy, not in the original array but in my copy. I need to do the same in the available 77 00:07:15,790 --> 00:07:20,770 products but there I first of all need to find the index because that index here only works for the user 78 00:07:20,770 --> 00:07:25,230 products, the index in the available products is very likely a different one, 79 00:07:25,750 --> 00:07:32,200 so I have my available product index here if you want to call it like this, which generally has the 80 00:07:32,200 --> 00:07:37,330 same selection logic, so we can copy that but of course I will look into the available products array 81 00:07:37,420 --> 00:07:45,660 instead of the user products array. And now again, here we can have the updated available products where 82 00:07:45,660 --> 00:07:53,280 I copy my state available products and then I set updated available products for the given product 83 00:07:53,340 --> 00:08:02,110 index equal, excuse me for the available product index of course equal to the updated product, 84 00:08:02,410 --> 00:08:07,810 so that I replace my existing product with the updated product in both the available products and the 85 00:08:07,810 --> 00:08:15,030 user products array. Well and now, we just need to return our new state, first of all copy the existing 86 00:08:15,030 --> 00:08:23,490 one and now set available products equal to updated available products and set user products equal 87 00:08:23,490 --> 00:08:32,790 to updated user products, so to my updated arrays I'm configuring up there. With that, we hopefully have 88 00:08:32,790 --> 00:08:38,880 all the logic we need, now let's dispatch these events from inside the added product screen. So here we 89 00:08:38,880 --> 00:08:46,440 need to import use dispatch from React Redux and import our actions, so import everything as products 90 00:08:46,530 --> 00:08:54,910 actions from the store folder, there from the actions folder and there from the products file and then 91 00:08:55,360 --> 00:09:01,060 dispatch these things in the submit handler of course. Here, what we dispatch depends on whether we're 92 00:09:01,150 --> 00:09:02,540 editing or adding 93 00:09:02,650 --> 00:09:08,110 amd as I mentioned, we can find out what's the case with the help of edited product, if it's set, we're 94 00:09:08,110 --> 00:09:11,100 editing, if it's not set, we're adding. 95 00:09:11,100 --> 00:09:18,370 So in here, in the submit handler, we can add an if check and check if edited product, if that is set, we're 96 00:09:18,460 --> 00:09:19,170 editing, 97 00:09:19,300 --> 00:09:25,660 so then I want to dispatch my update product event, for that, first of all, I need to create that dispatch 98 00:09:25,660 --> 00:09:33,650 function with the help of use dispatch and now with that created, down there we can call dispatch 99 00:09:34,310 --> 00:09:39,410 products actions update product because that's what we're doing here 100 00:09:40,570 --> 00:09:42,700 and now forward all the data we need here 101 00:09:42,700 --> 00:09:44,980 which is my prod ID, 102 00:09:45,130 --> 00:09:49,060 that's the ID of the product we're editing, we're extracting that up here 103 00:09:51,850 --> 00:09:59,020 and of course in addition, also forward the title, forward the description, all these state constants 104 00:09:59,050 --> 00:10:07,630 we have here, our imageUrl and not the price because we don't need that and in the else case here, 105 00:10:07,630 --> 00:10:09,060 that means we're adding, 106 00:10:09,130 --> 00:10:13,560 then I want to dispatch products action.create product, here 107 00:10:13,660 --> 00:10:21,850 we forward title, description, imageUrl and also the price 108 00:10:21,900 --> 00:10:26,580 and with that, we should have a setup where we hopefully can add and edit products. 109 00:10:26,640 --> 00:10:28,040 So let's save this and 110 00:10:28,050 --> 00:10:36,060 let's take a look. If we now go to the admin area here and I added this and I add an exclamation mark here 111 00:10:36,120 --> 00:10:43,460 and also one here in the description and I hit save, I get undefined is not an object, evaluating props 112 00:10:43,460 --> 00:10:45,440 price to fixed. 113 00:10:45,530 --> 00:10:49,540 So looks like I lost my price here when trying to update this. 114 00:10:49,850 --> 00:10:54,140 Well okay before we fix this, let's see if adding a new product works at all. 115 00:10:54,260 --> 00:11:00,890 If I add a product here with test, test which is of course not a valid imageUrl, so we'll not see an 116 00:11:00,890 --> 00:11:06,750 image but at least we sip at something, this is also a test. 117 00:11:06,830 --> 00:11:10,250 If we try this and I hit submit, this also doesn't work, 118 00:11:10,250 --> 00:11:13,220 so somehow saving the price doesn't work 119 00:11:13,220 --> 00:11:19,700 and I think the problem is here of course, the problem here is that price is actually a string here but 120 00:11:19,700 --> 00:11:24,890 should be a number, so we can easily convert it to a number by adding a plus here before we pass it to 121 00:11:24,890 --> 00:11:33,580 create product, for updating on the other hand, if we have a look at our products reducer, it should normally 122 00:11:33,580 --> 00:11:36,790 keep the price it already had. 123 00:11:36,850 --> 00:11:42,870 So let's see if that plus fixes it for adding or if there is a different issue as well, 124 00:11:42,880 --> 00:11:48,060 this was a change that's required anyways but let's see if there is another problem. So 125 00:11:48,060 --> 00:11:54,330 test, test, twelve please enter only numbers here, not some text which you currently could but which would 126 00:11:54,330 --> 00:12:02,950 break it, test this, press this button, yes that doesn't look too bad, 127 00:12:02,950 --> 00:12:09,920 we got some problem with the image here but if we scroll down, actually here if we dismiss this, we can 128 00:12:09,920 --> 00:12:14,030 see here's our product, 129 00:12:14,040 --> 00:12:18,290 so price is missing, so something's wrong there 130 00:12:18,390 --> 00:12:22,380 and we also don't seem to save the image correctly, 131 00:12:22,380 --> 00:12:25,400 not only because it's not displayed but because of that warning we got 132 00:12:25,740 --> 00:12:27,570 but generally, this works. 133 00:12:27,570 --> 00:12:31,650 However for example here if I try to update and save this, we still get an error, so there's still 134 00:12:31,650 --> 00:12:33,320 something wrong. 135 00:12:33,360 --> 00:12:39,270 So one thing that's wrong is in the actions of course, for update product here, the type should be update 136 00:12:39,270 --> 00:12:41,100 product and not create product, 137 00:12:41,100 --> 00:12:45,710 otherwise we trigger the wrong action in the reducer which explains the price error we got there. 138 00:12:45,720 --> 00:12:50,190 So this has to be update product here for updating a product unsurprisingly. 139 00:12:50,400 --> 00:12:57,060 So that's one problem but another big problem can be found in the added product screen. I use my use 140 00:12:57,060 --> 00:13:00,580 callback method here to wrap the submit handler right and I do this to avoid 141 00:13:00,660 --> 00:13:03,480 unnecessary recreations of the functions. 142 00:13:03,480 --> 00:13:08,730 The problem is I initially set this to have an empty array as a dependency list which means this never 143 00:13:08,730 --> 00:13:12,740 is recreated which made sense when we only had console log in there 144 00:13:13,230 --> 00:13:17,100 but now we're doing stuff in there and now we actually do have dependencies. 145 00:13:17,100 --> 00:13:22,710 Right now I never recreate this function which means it never is recreated for its updated values. 146 00:13:22,710 --> 00:13:28,180 So when we submit our form, we never take into account what the user entered. 147 00:13:28,200 --> 00:13:30,930 So actually now we need to specify dependencies here, 148 00:13:31,020 --> 00:13:40,590 the dispatch function but more importantly even, the prod ID, the title, the description and the imageUrl 149 00:13:40,680 --> 00:13:49,380 and also of course the price. Now with that if we save this, we should be fine and all the 150 00:13:49,380 --> 00:13:50,880 issues should be gone. 151 00:13:50,880 --> 00:13:52,220 So let's wait for this to reload, 152 00:13:52,290 --> 00:13:59,510 go to admin now and start editing this maybe and now if we add an exclamation mark in the title and in 153 00:13:59,510 --> 00:14:05,660 the description and we save this and go back, we see that here and if we go to products, we also see it here 154 00:14:05,720 --> 00:14:09,090 and in the details, we also see that exclamation mark. 155 00:14:09,170 --> 00:14:12,910 Now if we go back to admin and create a new product, 156 00:14:13,080 --> 00:14:15,200 test, test, 157 00:14:15,390 --> 00:14:21,790 twelve, test this and I save this and I go back, 158 00:14:21,890 --> 00:14:26,780 now this also shows up down there. Of course the image doesn't show up because we haven't entered a valid 159 00:14:26,810 --> 00:14:31,480 URL but all the other data shows up, so this is generally working 160 00:14:31,550 --> 00:14:35,410 and of course you could enter a valid imageUrl and that would also break, let's quickly test 161 00:14:35,410 --> 00:14:44,450 this as well. So let's go back to the admin section and add a shelf here maybe, for that I selected the URL 162 00:14:44,470 --> 00:14:53,970 of a shelf I found on the internet for 199.99, this is a nice 163 00:14:53,970 --> 00:15:00,870 shelf like this. If we now save this and we go back, this looks good, here's our image and we also 164 00:15:00,870 --> 00:15:05,260 see that here on the product screen and we can view it here as well. 165 00:15:05,730 --> 00:15:07,070 So this seems to work 166 00:15:07,080 --> 00:15:11,610 and with that, we generally have a set up that does work. 167 00:15:11,610 --> 00:15:16,410 Now there are minor things which I want to work on, for example before we delete, it would be nice to have 168 00:15:16,410 --> 00:15:23,310 a little confirmation dialog and in addition, I want to make sure that when we added or edited a product, 169 00:15:23,400 --> 00:15:26,140 when we click save here, we automatically navigate back. 170 00:15:26,130 --> 00:15:31,590 So these are just minor things of course but I think they make for a nice final here in this module.