Often to get user data you'll make an AJAX request using axios
or the fetch
API. In this lesson we'll get a GitHub user's company using GitHub's GraphQL API using React's componentDidMount
lifecycle method.
Instructor: [00:00] We'll start out with a class called userCompany. That extends a React component. Then that'll have a render method. We're going to say return this.state.company, or unknown. Then we'll go ahead and initialize our state here with company is undefined.
[00:20] Then we'll use that userCompany here with userCompany, and we'll pass the username prop. We'll use that later, and get rid of to. Next, we're going to do a componentDidMount, and we're going to need the Axios library.
[00:36] I'm going to go ahead and paste a script for the Axios library in right here. We're going to make a request here with a couple options. Our URL is going to be https://api.github.com/graphql. Then the method will be post.
[00:54] The data will be query as a string. This is going to look like an object, but it's a GraphQL query. We'll say user login, this.props.username, and we're going to get the company for the user that we pass in here.
[01:16] Then we need to add headers for authentication. We'll say authorization and error token. We need to get that token from somewhere. We'll go to GitHub, and go to settings. We'll go to our developer settings, personal access tokens.
[01:39] We'll generate a new token. We'll call this userCompany, and we only need the user read/write. We'll generate that token and copy that. Then we'll paste that in here. Now, when that request finishes, we'll say then we'll take the response, and we'll say this.setState. Company is the response.data.data.user.company.
[02:08] Make sure we're using the right variable. Cool. Now, we get Kinsey Dodds works at PayPal. Let's go ahead and say that the request takes a little bit of time. We see that blinks unknown really quick there.
[02:20] It's not that it's unknown. It's that we don't know it yet. We haven't completed the request, so we're going to add justLoaded is false to our state here. Then when we set the state, we can say loaded is true. Then we'll say this.state.loaded.
[02:38] If it's loaded, then we'll do this. Otherwise, we'll do dot-dot-dot. Now, we get the dot-dot-dot, and then @PayPal. We can use somebody else here, too, Enza Bariski, and he works at Instructure.
[02:56] In review, to make an asynchronous request, you're going to use componentDidMount. You can use a library like Axios to make a request, and when that request resolves, you setState. Then you render that state in your render method.
[03:10] Now, if there happened to be an error with this request, then we could add an error handler. In here, we could say this.setState with error and loaded is true. Then we could reference this.state.error in here, and do something different in the error case.
Hi Jared, Yes, you could definitely set it to null. It doesn't really make much of a difference here. I'm glad you like the series!
axios is not defined
Where is the best place to put HTTP requests? I noticed you did in componentDidMount(), would it be wrong to put it in componentDidUpdate()?
It depends on what you want to do. If you want to run the HTTP request only when the component is initially mounted then you can use componentDidMount
by itself. If you only want it to run when the component is updated, then you can use componentDidUpdate
by itself. If you want it to run both when it's initially mounted and when it's updated (like if the company name can change over time), then use both (this is normally what you want).
Thanks Kent! This series have really helped me a lot!
Hi Kent I think this code is wrong <code>return this.state.error ? this.state.loaded ? this.state.company || 'Unknown' : '...' <code> May be you mean this <code>return this.state.error || this.state.loaded ? this.state.company || 'Unknown' : '...' <code>
Hi Kent I think this code is wrong <code>return this.state.error ? this.state.loaded ? this.state.company || 'Unknown' : '...' </code> May be you mean this <code>return this.state.error || this.state.loaded ? this.state.company || 'Unknown' : '...' </code>
@sergey I think that is not an error. What that means is
js if (this.state.loaded) { if (this.state.error) { return "ERROR (You probably need to add your own token)"; } else { return this.state.company || 'Unknown'; } } else { return '...'; }
@Brahma Reddy see https://codepen.io/anon/pen/LaENMJ
https://prnt.sc/mqdykc
@sergey Kent set the logic up properly, in my view. Basically it's checking what to return by asking "did we load the data?" and if it did then it asks "was there an error?". If there was, then we tell the user "This was your error" or we say no, we got what we wanted, and return this.state.company || 'unknown'
.
Then a step back to the first ternary expression to say that you simply return "..." if the data didn't load correctly.
@Erik final solution is ok. https://codesandbox.io/s/github/eggheadio-projects/the-beginner-s-guide-to-reactjs/tree/codesandbox/17-make-http-requests-with-react
But try run code from video on 3.29 https://prnt.sc/mqdykc
Or check final version render() method in transcript
@Sergey I see what you mean. It's hard to spot those changes between the video and the final code! That was basically trying to check if the data loaded when the error DID occur. Maybe Kent was trying to make the laws of javascript logic bend to his will.
@Erik No problem ). Main point that solution in codesandbox is good.
Hi there,is it possible that a portion of the video is missing? The code seems to go a step further, adding an update on componentDidUpdate, but the video stops berfore. Is that last portion available somewhere? Thanks!
explicitly setting a value to undefined seems like a bad idea, shouldn't we use null there? Enjoying this series, thank you for your work.