- Read Tutorial
- Watch Guide Video
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.
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
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.
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.
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.
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.
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"