How to Build a Newsletter Archive Detail Component and Pass in Data
Welcome back to the course. So before we get in the actual functionality of our buttons in the back-end, let's make it so we can click on our archived items and bring them up like they're the latest newsletter.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

All right so if you go to the Invision app design, and you click on the titles of our archived items, it brings us to this.

large

We want to see something like this. Now luckily we've already kind of built all these components so it should be pretty quick. Let's go ahead and build it. So we need an ID because we want to click on it, and we need it to take us to an archive route.

So let's create that route. Let's go to bootstrap.js and then here let's just copy this route and let's say detail.

bootstrap.js

<Route path='/newsletter/detail/:id' component={requireAuth(NewsletterDetail)}/>

We want it to hit newsletter detail, so let's go ahead and create this component in our newsletter folder and call it newsletterDetail.js. There we go. Well, let's go ahead and start writing our component.

newsletterDetail.js

import React, { Component } from 'react';

class NewsletterDetail extends Component {
    render() {
        return (
            <div className='newsletter-detail'>
                Newsletter Detail
            </div>
        )
    }
}

export default NewsletterDetail;

Now let's import it into bootstrap.js

large

Now that we have the route set up, all we have to do is make it so when we click one of those items, it sends us to this route and passes in an ID. We've done both of those before so let's do it pretty quickly.

Let's head over to our newsletterArchive.js and you can see all of our archived items. Right now they're just div items, and we need to make them an 'a' tag so we can click on it and then let's provide it with a function or a callback. Either way is OK.

newsletterArchive.js

function ArchiveItem({title, date, _id, callback}) {
    return (
        <div className='archive-item archive-items__item'>  
            <a onClick={() => callback(_id)} className='archive-item__title'>{title}</a>
            <div className='archive-item__date'>
                { date.getMonth() + 1 }
                /
                { date.getDate() }
                /
                { date.getFullYear() - 2000 } 
            </div>
        </div>
    )
}

Inside of our component itself, we are using the spread operator on newsletter. We're also putting it in the key but we're not even allowed to use the key. So we'll just get it from the id.

Let's add in this callback function.

newsletterArchive.js

class NewsletterArchive extends Component {
    render() {
        return (
            <div className='newsletter-archive'>
                <div className='newsletter-archive__title'>Archive</div>
                <div className='newsletter-archive__items archive-items'>
                    {/* newsletter items */}

                    {
                        this.props.newsletters.map(newsletter => {
                            return <ArchiveItem callback={(_id) => console.log(_id,'trying to push to detail route')} key={newsletter._id} {...newsletter}/>
                        })
                    }
                </div>
            </div>
        )
    }
}

Let's test it out and click on one of the items in our archive.

large

You'll see it says '115, trying to push to detail route'. So we now have access to the ID. Now we need to do is push it to a route and pass in the ID with it.

newsletterArchive.js

class NewsletterArchive extends Component {
    render() {
        return (
            <div className='newsletter-archive'>
                <div className='newsletter-archive__title'>Archive</div>
                <div className='newsletter-archive__items archive-items'>
                    {/* newsletter items */}

                    {
                        this.props.newsletters.map(newsletter => {
                            return <ArchiveItem callback={(_id) => this.props.history.push(`/newsletter/detail/${_id}`)} key={newsletter._id} {...newsletter}/>
                        })
                    }
                </div>
            </div>
        )
    }
}

Let's see what happens when we go to that route.

large

We get an error that says "cannot read property of 'push' of undefined". The reason that's happening is because it doesn't have access to history. Previously, the way i've shown you how to use history throughout other components is by simply passing them down, like in newsletter grid.

Now I want to show you another way of doing this because I don't want to just get you hooked on one way of doing things. We need to be versatile and have multiple approaches. So let's go into our archive and let's import history.

large

We are simply providing history to our router by importing it. So it's the same history. Let's go back to our newsletter archive and uses history instead of this.props.history.

newsletterArchive.js

class NewsletterArchive extends Component {
    render() {
        return (
            <div className='newsletter-archive'>
                <div className='newsletter-archive__title'>Archive</div>
                <div className='newsletter-archive__items archive-items'>
                    {/* newsletter items */}

                    {
                        this.props.newsletters.map(newsletter => {
                            return <ArchiveItem callback={(_id) => history.push(`/newsletter/detail/${_id}`)} key={newsletter._id} {...newsletter}/>
                        })
                    }
                </div>
            </div>
        )
    }
}

So let's go into our browser and let's try this out by clicking on one item.

large

You'll see it takes us to a blank screen that in the top left that says newsletter/detail/115. All right let's go back and try clicking on the second newsletter. You'll see it takes us to the same route says the same thing, but this time we have a different ID in our recall.

By doing this we can really easily fetch our item and get the specific data we want and what makes it even easier is that we've already written this function specifically for when we edit items, so it should be really easy. All we have to do is hook up our component to redux and our actions and fetch the newsletter letter with ID.

After doing that all we need to do is throw in our data. So since we are kind of on roll of understanding how this is working with the fetching of items via the ID, lets go ahead and in the next video we'll hook up our component to react-redux and connect, and we'll console log the it and continue to build out the layout and get it appearing on screen.

Let's commit our code.

git status
git add .
git commit -m "built newsletter detail route and component and setup to newsletter id via req.params"

Resources

Code at this stage