Building the Review Product Component
All right welcome back to the course. Let's go ahead and look at our application and let's see what it looks like.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So we have order review and then we have this in our application. So this is what we're doing is we're printing out each item individually right by mapping over it, so for the most part it's setup. All we need to do now is we need to create a custom component to display those rather than just an h1 tag. Okay, so let's do this, it should be really quick and easy. We already have all this data, we don't have an image though so we need to introduce an image into our model or just display an image like that.

So let's go to our code and what I want to do is I want to head over to user.js in actions and in our fetch cart products what I want to do is introduce an image url. So let's go to fetchCartProducts and put a comma, then let's say image url okay. And then what we'll do this is for the icon we'll just say http:// well actually what we'll do... yeah we'll do that because you don't have access to the images, I don't have them either right now.

Okay, so http://via.placeholder.com/80x80 I think that's how big it is. Let's go ahead and check in the design, yeah 80x80 wow, okay so again go into user.js in actions and on fetchCartProducts you want to add an image url to the products okay, so both of the products, add that in.

Now this is great, but there's a catch and I'll show you when we get around to actually adding these products or when we are displaying them with the image okay. Let's... I'd show you now but I want to show you because it will help you understand our models better and how we're getting the products in here when we add new ones if you forgot how.

Okay, let's close out user.js and in reviewProducts.js we want to create a component. So what I'm going to do is create a new file and I'm going to call it reviewProduct.js so a really close name, but it's alright. import React then the component from react and let's say class ReviewProduct without an s, extends Component, let's render out a div let's make sure we return it and let's give it a className of just review-product. We don't need to take in a custom class name because there's just going to be a whole bunch of them and there's no special position we need it in on a grid. Export default review product and we're set.

reviewProduct.js

import React, { Component } from 'react';

class ReviewProduct extends Component {
    render() {
        return (
            <div className='review-product'>

            </div>
        )
    }
}

export default ReviewProduct;

Now what we need to do is basically introduce each item we need in here okay, so we need the image, the name, the quantity, and the price. So we need an image we'll give it a className of review-product__image source is going to be image like that.

<img className='review-product__image' src={image}>

Then we need a name, so we'll say div and then we'll say className is review-product__title and we'll say product title so we'll say title, then we'll say div and then we'll say className is equal to quantity or was it price? They're both in there but which ones first? Okay, quantity.

So we have review-product_quantity, and we'll put quantity in here and don't import quantity, that was a mistake just type in quantity and don't hit return. Okay, we'll say div and we'll say className is equal to review-product_price, and what we're going to do here is we're going to say price times quantity because we want to get the total price like it. It doesn't show you in the design but if you go into design it says quantity 1 price $1.99.

large

If this were 2 I would imagine we would want it to say like whatever two times two is right so four bucks. We want it to say like $3.98 right here, so we want to multiply price by quantity, you get that and then we'll put a dollar sign in front of it. And then remember how we build a green title label component? We want to use that so let's say GreenPriceTag, import GreenPriceTag from ../greenPriceTag and let's basically just put in this className, and then we'll say title is equal to price times quantity okay. Then it has that dollar sign in this green styles automatically.

reviewProduct.js

import GreenPriceTage from '../greenPriceTag';
return (
    <div className='review-product'>
        <img className='review-product__image' src={image}/>
        <div className='review-product__title'>{title}</div>
        <div className='review-product__quantity'>{quantity}</div>
        <GreenPriceTag className='review-product__price' title={price * quantity}/>
    </div>
)

So that sets us up, let's go ahead and view this in the browser now. Let's go into our application and we don't have anything because we're not using it. Okay so what we need to do is first, I'm going to see what that is, okay that's something else. Okay, so we need to use this, let's go into reviewProducts.js, and instead of returning an h1 let's first import ReviewProduct from ./reviewProduct into our reviewProducts.js component, and let's use it instead of an h1, let's say ReviewProduct, so what we need to do is we need to get rid of all this and close it off like so, then what you do is when you put this on a new line so we can see it better.

reviewProducts.js

import ReviewProduct from './reviewProduct';
<div className={'${className} review-products'}>
    {
        this.props.cartProducts.map(cartProdut => {
            return <ReviewProduct key={cartProduct._id}

            />
        })
    }
</div>

So we have our key and we don't need a className, so all we really need now is ...cartProduct. Okay, so we're putting the entire cart product into our review product okay. Now if we try to run this, this is not going to compile. So let's go into Chrome... so it most likely won't compile, okay it compiles but it doesn't show anything because as we're putting this in it's working, except for it's not displaying anything because back in reviewProduct.js none of these are defined.

So we need to take those out of our props by going into our render function and saying const and then we need to say product and quantity is equal to this.props okay we're pulling it out of the cart product we provide and then let's say constant imageUrl, title, and price comes from the product within our cart product and then let's make sure this image source is imageUrl okay, so we're set. Get all these outlines in here, it's about 19 lines so I'll give you a second to do that.

reviewProduct.js

import React, { Component } from 'react';
import GreenPriceTage from '../greenPriceTag';

class ReviewProduct extends Componet {
    render() {
        const { product, quantity } = product;
        const { imageUrl, titel, price } = product;
        return (
            <div classname='review-product'>
                <img className='review-product__image' src={imageUrl}/>
                <div className='review-product__title'>{title}</div>
                <div className='review-product__quantity'>{quantity}</div>
                <GreenPriceTage className='review-product__price' title={price * quantity}/>
            </div>
        )
    }
}

export default ReviewProduct;

And basically just to explain again while you're typing that in, we have product and quantity as a part of the cart product, then we have imageUrl, title, and price coming out of the product. So let's go to user.js in our actions, okay so we have the product and the quantity again. So let's go back to review product, we have the product and the quantity, and then in the product we have the title and the price in the imageUrl that we need access to.

Okay we don't need any of the other ones inside of product, we just need imageUrl, price, and title. So we're pulling that out of product which we pulled out of our cart product which we are spreading into our review product from within reviewProduct.js right here. Okay, so hopefully that makes sense, that's the best I could explain right now off the top of my head, and I think that you should understand.

Okay, so let's go see what this looks like now, okay let's hit back, let's add a product to our cart like full stack, let's hit checkout, and you'll see we now all of our products here, so that's really nice. And then like I told you there's going to be a catch with the imageUrl, see how the first two have an imageUrl but the second one doesn't?

large

Let me explain why that is, the reason we don't have an imageUrl on the second one is because in our code right here(reviewProducts.js line 11) remember in user.js we have an imageUrl that we added in at the beginning of this video. We only added that into the fetch cart products all right. So copy that and let's head over to the shop.js action.

Okay, when we fetch the products none of these products contain that, and we're adding these products to our user cart product array. So let's go ahead and on each of these we'll paste it in okay, and even if you want to be quick you can just grab the end of this and since these brackets only exist at the end of belongs to we can just hit command d and paste it right there.

Well make sure you put in the bracket again so say bracket and paste it, there we go so just make sure each one of these has an imageUrl all right.

large

Now when you go in here and you go back and you add in products and then you check out it should give us the imageUrl but it's not. Okay, so maybe we didn't reload it, let's try reloading it one more time. Okay, let's hit all, let's add in a product, let's hit check out. It look's like the imageUrl isn't there, so that's a problem, yeah that's definitely a problem... I wonder why that is.

Let's go ahead and do this okay, imageUrl, let's try this. Let's go to our application let's hit back, let's reload the page and let's hit redux dev tools then hit to the left, so we should be able to see all of our products right. And they should contain an imageUrl it looks like it does, right cart products contains the imageUrl within the product.

large

But for some reason when we're pushing to here it's not containing the imageUrl which is interesting. Let's try adding a cart product, okay so notice how in the dev tools cart products is 2 right. Let's add another one like full stack and see what happens. Okay, cart products 2 doesn't contain the image, so what we need to do is check where we're adding this cart product and see why it's not adding all of the properties in here... and I know exactly why, I just remembered. Okay, and this is kind of a design fault on our part.

All right, so the reason it's happening is because if you remember when we add to that we didn't want to add the entire object because we didn't want it to contain the key remember? What we did was we pulled them out of props. So let's see where did we do this, addCartProduct in shopProduct.js you see, this is exactly where we're doing it.

We need to pull out imageUrl in here, so shopProduct.js on line 13 or so, around there. We need to pull out the imageUrl from the props and put it into addCartProduct.

shopProduct.js

handleAddToCart = () => {
    if(document.getElementById('shop-cart').classList.contains('cart-hidden')) {
        document.getElementById('shop-cart').classList.remove('cart-hidden');
        const { _id, title, description, price, belongsTo, imageUrl } = this.props;
        this.props.addCartProduct({ _id, title, description, price, belongsTo, imageUrl });
    } else {
        document.getElementById('shop-cart').classList.add('cart-hidden');
    }
}

So little design flaw on our side, if we had an actual backend hooked up here this wouldn't be a problem, but don't worry about it. So now what we need to do is go into our application and test this out one more time. So let's hit all, let's add in graph database, we already had that, let's go down add javascript, I think we already had that too, we had JavaScript in the browser at least. Okay, let's add in user experience, make sure you're closing it out each time, because we haven't implemented the hover, or the backdrop here that shouldn't allow us to do this, like we should only be able to interact with the card at this point but we don't have the backdrop there yet, but we're going to add that when we get around to fixes.

So let's hit check out, you'll see they all have images now.

large

Okay sweet, so that's how you update those models and include an imageUrl okay, and that's how we get all the data in there. So we need to do one more thing before we end this video and it's basically setting the overflow-y so this scrolls instead of extend's okay. And then what we need to do in the next video is basically put this all on a grid and then style it.

Okay, so let's try making this scroll instead of overflow. So let's go into, let's see what did we call it... reviewForm.scss okay, so in &__products what we want to do is say overflow-y, so let's see if this works.

reviewForm.scss

&__products {
    grid-column: 1/-1;
    grid-row: products-s/products-e;
    overflow-y: scroll;
}

Okay, you'll see it now scrolls and that it looks really nice. Now if you want to make it go down more feel free to change the values. I remember it was about 400 pixels we did, you could go and change that. You could go into review.scss and changes this to like 525 pixels if you want, just feel free to do whatever you want.

I actually recommend that you play around with this because it will teach you how to kind of work with CSS and build things the way you want. Again the point of this course isn't entirely to show you how to duplicate this app, it's to show you how to build this app with a set of skills all right. And those set of skills will allow you to build other apps specifically for clients and employers all right, that's the whole point.

So let's go ahead and let's move on to the next video where we'll handle the grid and the rest of the styling for this component and basically finish off this component so we can move on to the title and the next page here. So let's go commit our code.

Terminal

git status
git add .
git commit -m "built review product component"

I'll see you in the next video.

Resources

Source code