- Read Tutorial
- Watch Guide Video
So let's see what we need to do in order to get this working. We have our Blog detail component, and let's just review how it is operating. If you click on one of these links from the blog component, such as Testing from modal, then we're taken to this Blog detail component, and as you may notice, up here, the route changes. It changes to that custom route that we created, slash b, and then we have the ID.
Now, that ID is critical, 'cause what we're gonna have to do is reach up into that URL and we're going to have to grab that parameter, because we are going to contact the DevCamp Space API and we're gonna say, hey, I have a blog with this ID, I need you to send me all of the data for that blog, and so that's what we're gonna do here in this guide.
We're not gonna render it out on the page quite yet, we're gonna start by simply calling the API and just printing out to the console what the data is, and then we'll start to break it into what we're gonna render in the next few guides. So right here, the very first thing that I'm gonna do is create a constructor, and so this constructor is going to be able to initialize our state, and we're also going to add in all of the necessary boilerplate code.
So I'm gonna start off by calling constructor, we're not gonna pass in any props or anything like that right now, we are simply going and we're grabbing that URL. So make sure to call super, and we're not passing in props to super, either, and then for the state, I'm gonna say this.state equals, and then inside of the initial state object, I'm going to say currentId
. You could call this blogId
, you could do anything you want with it, but for right now, I'm just gonna say this is the currentId
, when we're on this page, this is gonna represent whatever the current state of the ID is.
Now, if you remember back, we've done this a few times, but I will tell you, if you're anything like me, this next part is something that you may have to perform a few times. I know I'm constantly having to refer back to make sure that I understand or that I remember the exact syntax here.
So in order to grab those parameters from the route, what we do is we call this.props and I already realize that I made a slight mistake. I said we don't have to take any props in, and this is a good lesson here. We're not passing props directly from the blog component into the blog-detail component, however, we do need to call props.
We're actually calling the props from the route and so I'm going to pass props into the constructor and into the super call, and let's just take a little side trip and see exactly why we have to do this, because this will hopefully help you really understand the way that the routing system works, hopefully even more.
So let me open up the app component, and you remember when we created this route right here. We passed in the path and then we said the component is gonna be BlogDetail, we already did that, and it works. Behind the scenes, what the React router system does is it is passing in props directly to our component.
Now, we didn't explicitly pass these props, but if we call our properties, right here in the constructor and in the super call, we have access to them. This would also work if you were building out this with a functional or presentational component.
We have to call props because we need to be able to access the route parameter. If I did not have props called right here, I wouldn't be able to call the route, because I wouldn't be able to reach up into the routing system to grab that, so that is actually a good lesson, and that would've been an error, so I think we have that fixed now.
So I'm gonna call this.props.match.params.slug
. That is a mouthful, do not feel bad if you do not have this memorized. I write React code and Vue code pretty much on a daily basis, every time I need to go grab the parameters from the URL, I almost always have to go look it up or I'll mistype it the first time.
Whenever you have to call one, two, three, four, and five methods all together, that is something you don't have to do on a regular basis, so don't worry if this feels weird or it feels like something that you may not remember, simply use your previous code you've written to reference back to it, because that's exactly what I do and it's what most developers I've ever known do.
So now that we have that currentId
, that is going to be set, and we can test this out right here. So let's come down into the render method and let's just console.log this. I'm gonna console.log the currentId
and I'm gonna put that as a string, and then I can say, this.state.currentId
, hit save, and let's just make sure that everything's working up to this point, because if I type something wrong here, we have an error, I don't wanna go any further down the line, I'd rather have it fixed nice and early.
So let's switch to Google Chrome, open up the console right here, and you can see when we did the auto-reload, it already printed this out for us, but you can always clear it out, hit refresh again, and you can see it's printing out the currentId
is 20.
If you're curious on why it printed it out twice, I would recommend that you go back to that deep dive we did on the component lifecycle methods, and you'll see that the render method in React is actually called multiple times when a component loads, and so that is the reason why that is being triggered.
So right now, we have access to that ID, and let's just check one more thing, because you can never do too much testing. If I come back to the blog component, let's go down to one of the other posts, so I'm gonna click on this one. You can see currentId
is 18, so that tells me this is dynamic, it is the actual ID, so everything there is working properly.
Now that we have that, we know we're going to have to populate our current blog, so what I'm gonna do is give us a starting state for our blogItem
, and the starting state's just gonna be an empty object, so whenever BlogDetail's initialized, it's gonna start off as an empty object, and then what we're gonna do is we're gonna replace this with the response from the API.
Let's now create that method, we know we're going to call Axios, so before we get into typing too much, make sure you go up to the top and import axios
from axios
so that we can contact the outside APIs, and now let's actually write this function.
I'm gonna call it getBlogItem, and we're not gonna pass in any arguments, and the reason why we don't have to pass in any arguments is because we're gonna be pulling from this currentId
state. So now I can call axios.get
, because we're wanting to pull in, we're wanting to go and query a value, and inside of get, I'm gonna use the backtick, so use two backticks, and that's because we need to make this string dynamic.
Now, I'm gonna type H-T-T-P-S colon slash-slash A-P-I, or actually, jordan.devcamp.space slash portfolio, slash portfolio underscore blogs, slash, and this is where we're gonna use our string literal here, dollar with curly brackets, opening and closing, and inside of here, I'm gonna say this.state.currentId.
So let's hit save and that way, our auto-formatting works right here, and that's all that we need to do.
blog-detail.js
getBlogItem() { axios.get( `https://jordan.devcamp.space/portfolio/portfolio_blogs/${this.state .currentId}` ); }
The reason why we don't have to pass in with credentials true here, is because I made these API endpoints open to the world. Sometimes, whenever we're doing something such as creating an item, for security purposes, we need to pass in your own cookie, so that you can be authenticated by the server.
But for things like this, a blog is something, if you're writing it, you wanna share that with the world and so right here, we're simply passing in the regular URL with the ID, and then we don't have to prove that you are who you say you are, because we're gonna allow anyone to view that data, 'cause it's public.
So that's everything we need for the get call, now we have to say what we want to happen when that promise gets resolved, when the data gets back. So I'm gonna say then, and then response, with an arrow function, and like I mentioned, right now we're just gonna worry about console logging out the response, just to see what kind of data we have to deal with, and make sure to always catch your errors and we're just gonna console.log the error here, but I like it to be descriptive, so we're gonna say, console.log getBlogItem error and then we wanna see whatever that error was.
So that's gonna go out and get the blogItem
, and now we have to make sure that that's triggered whenever the component has been loaded, so I'm gonna add a lifecycle method here called component, and this time, I'm just gonna say, componentDidMount and now I can call this.getBlogItem and call it as a regular function.
So let's test this out and see if we get a response back. So I'm going, you don't even have to refresh if you hit save, you can see, we have our response here and we have data, this data right here, is giving our portfolio_blog record from the server.
It says it's in status of draft, it has all of the metadata, it has the content, the image, and yours might be blank if you didn't upload an image. It has the ID, and then the title, so this has everything that we need.
Now that we have the data coming in from the server, in the next guide, we're gonna update our component state and then we're going to start rendering the content onto the screen.