Check out a free preview of the full Complete Intro to React v4 course:
The "Adding an Input from API Data" Lesson is part of the full, Complete Intro to React v4 course featured in this preview video. Here's what you'd learn in this lesson:

Populate a select list of options based on the returned list of breeds from the Petfinder API based on the animal you have selected. Call getBreeds from the API after calling setState with the animal you have selected.

Get Unlimited Access Now

Transcript from the "Adding an Input from API Data" Lesson

[00:00:00]
>> Brian Holt: So we did animal change, and now we're gonna do something else, so we're gonna have a breed selector drop-down after animal, right? And the breed selector is going to be dependent on whatever is an animal, right? So if if switch from dog to cat, there's different types of breeds from cats and from dogs, and I have to request these from the API each time someone makes that call.

[00:00:28] So in other words, I select dog, I'm going to have to make an API request to get all the dog breeds and, yeah. So we're gonna make a drop-down populated with all those breeds.
>> Brian Holt: So the first thing that we're gonna do is we're going to make a getBreeds function.

[00:00:56]
>> Brian Holt: This doesn't need to be an narrow function cuz this is not going to be,
>> Brian Holt: This is going to be called from places where we don't necessarily need it for it to be an arrow function, and it's gonna say if (this.state.animal).
>> Brian Holt: So if I have an animal selected, I have to go getBreeds.

[00:01:22] If I don't have an animal selected, so I'm searching for all animals, it doesn't make any sense to have a breed list, right? So if I don't have an animal selected, I'm gonna say this.setState,
>> Brian Holt: breeds, and breeds are just gonna be an empty array.
>> Brian Holt: I guess the other thing is I need to add, do I have breeds?

[00:01:47] Yeah, so up here as well, underneath state, I have to add breeds as an empty array as well.
>> Brian Holt: So line 9 there, added breeds, breed, it's gonna be like the breed, the selector in breed. It's gonna be all the available current breeds that I could select from, okay?

[00:02:17]
>> Brian Holt: So if I have no animal selected, I will select breeds. Then I'm gonna go down here and will say petfinder.breed.list.
>> Brian Holt: And I'm going to search for animal,
>> Brian Holt: this.state.animal
>> Brian Holt: So this will give me a promise back of all the various animals or breeds that I can select from.

[00:02:54] So I'm gonna say .then(data).
>> Brian Holt: And here I'm gonna say, if data.petfinder and data.petfinder.breeds and data.petfinder.breeds.breed.
>> Brian Holt: Actually, I'm gonna have to wrap this, is array call.
>> Brian Holt: So make sure the petfinder exists, make sure that breeds exists, and make sure that breed isn't going to be an array of breeds.

[00:03:51] Cuz I think one of those animals, it might be the pigs or something like that, don't have any breeds and so you have to be defensive against that.
>> Brian Holt: And if that's the case, then we're gonna do,
>> Brian Holt: this.setState,
>> Brian Holt: Of breeds:data.petfinder.breeds.breed.
>> Brian Holt: Again, otherwise you're gonna set breeds to be just the same line as line 37.

[00:04:35]
>> Brian Holt: Empty.
>> Brian Holt: We have to go import petfinder at the top cuz we don't have it up there yet. So next time we need to do is import a petfinder client up here.
>> Brian Holt: From petfinder, it is important that petfinder comes before animals right here, so keep that in mind.

[00:05:02]
>> Brian Holt: And then we're gonna say,
>> Brian Holt: Sorry, pf is the way I was doing that before, const pf = const rather petfinder, pet finder = pf.
>> Brian Holt: And key is going to be process.env.API_KEY.
>> Brian Holt: The other one is going to be secret: process.env.API_SECRET.
>> Brian Holt: So now the petfinder down here will be available.

[00:05:51]
>> Brian Holt: So I just did import pf up here. I run this function here, which returns the petfinder singleton, which is just the same API client gets imported to every single,
>> Brian Holt: Place in the code base. Give it the key in secret, and then down here we can use that to request breeds.

[00:06:11] So now we have a working getBreeds function, so we actually need to use that.
>> Brian Holt: So when do we wanna select, or when do we wanna get new breeds in?
>> Brian Holt: Well, in general, we wanna get breeds whenever a person selects,
>> Brian Holt: A new animal, so if they go from cat to dog, we need to request new breeds, makes sense?

[00:06:43] So what you can do here,
>> Brian Holt: Well, first of all, it's tempting to do this.
>> Brian Holt: This is in general, how you would think that it should work, that if I call setState, immediately afterwards I would think. Okay we are done here, I'm just referring to this.state.animal, that should work.

[00:07:07] Because of how React works, this doesn't, if you remember what I said previously. React batches together all of your updates into one atomic update which means that if I call setState. I'm not actually guaranteed that, that's going to flush immediately, it might but in this case it probably won't be that fast, usually it's on next tick, or it sets timeout zero.

[00:07:34] So how do we make that work then, how do we get it to the point where we can guarantee that that's going to work? Well, there's a secret second function that you can provide to setState that it will run after it flushes. So I can just say, hey, whenever you’re done call this.getBreeds and that will work.

[00:07:59]
>> Brian Holt: The other thing here is, whenever we call animal and we update our animal. You probably wanna reset the breed because I don't wanna search for a cat husky, despite how awesome that sounds.
>> Speaker 2: [LAUGH]
>> Brian Holt: Doesn't make any sense, so we are gonna set breed to be empty string again.

[00:08:22]
>> Brian Holt: Does the getBreeds part of that make sense to you? Yeah?
>> Speaker 2: Even though the setState batches all of the updates all together, can we assume that when you add that call-back function that it would be synchronous then? So it'll happen after the setState?
>> Brian Holt: If you add that function you are guaranteed that it will be called after the setState is flushed.

[00:08:47] That's the guarantee that they provide you there.
>> Brian Holt: Does that answer your question?
>> Speaker 2: Yeah, I was just wondering if it will work, like your work's in a one-off, but what if you have some crazy app with, you needed it all to work synchronicity, like in a series?

[00:09:08] The part that's getting me confused is cuz you said, React will put all the setStates together, but it's able to track like, at what points to call those callbacks?
>> Brian Holt: Yeah, so if you have that complex orchestration, using setState as your coordinating method is probably not the best idea.

[00:09:32] There's an advanced feature of the latest version of React, which is React 16, which is what I'm showing you, called Time Slicing, which I will not be talking about. But that's what you wanna get into, is you can actually have a little bit more, I don't think it's actually even generally available yet, which is why I'm not teaching it.

[00:09:50] But it will allow you a little bit more granular control of how React does things, like you can set things as priority updates and low priority updates. So there is a new method coming called, defer setState.
>> Brian Holt: So that gets a little bit more into if you will need to be a little bit more governing of how things update.

[00:10:14]
>> Brian Holt: Cool, so now we need to make a handle breed change as well, handleBreedChange, this one is gonna be really simple.
>> Brian Holt: This.setState() breed is gonna be event.target.value, and that's all that needs to be.
>> Speaker 2: Spelling.
>> Speaker 3: BreedChange is spelled wrong.
>> Brian Holt: Cange, no, that's what I meant.

[00:10:50]
>> Speaker 2: Thank you.
>> Brian Holt: And then last thing, we have to go write our markup that shows it. We got one more label to put down here, Label htmlFor = breed. And when you put this as breed and stop that, select, and here, we're gonna put id = breed,

[00:11:28]
>> Brian Holt: value = this.state.breed.
>> Brian Holt: onChange = this.handle BreedChange, onBlur = this.handleBreedChange.
>> Brian Holt: And then we have to put one more thing here, if there's no breeds in the breed list we wanna disable that drop-down, right? Because if there's nothing we wanna show to the V user that that select is disabled.So we can put in here disabled equals and then we can use a ternary here,

[00:12:15]
>> Brian Holt: Actually, we don't even have to do that, so if this doesn't have any length, this.state.breeds.length
>> Brian Holt: Then this will be disabled. So think about this for a second. In fact, let's just go into my browser here and I'll show you, if I have const, all right, let's go and do that.

[00:12:43] We're using type coercion to our advantage, so if I have !0, it's gonna be true and if I have !1, it's gonna be false, right? So if this is not 0, so if the length is 0 then it's going to be disabled. If I have not anything more than like 1, 2, 3, it's gonna be false and so it will not be disabled, does that make sense?

[00:13:11] It's a little clever trick, you can also put in here, if disable triple = 0, this would work as well.
>> Brian Holt: I think I'm lazy so that's why I didn't put the not there but we can leave this in, this is probably a little bit more clear so.

[00:13:30] So if you have nothing in the breeds list then disable it. If you have anything more than that then don't disable it.
>> Brian Holt: Okay, and then we're gonna put down here a submit button that we will address later in the course. But for now, this submit button will do nothing.

[00:13:58]
>> Brian Holt: Okay, so now we have the select, we have to go and put our options in here.
>> Brian Holt: And here we're going to map over our breeds list that we've requested, after an empty option, this.state.breeds.map(breed, yeah, that's right.
>> Brian Holt: And we're gonna do, option key={breed} value={breed} and this text in it is breed.

[00:14:51]
>> Brian Holt: So we have a list of breeds that came back from the API and this is just what we wanna show to the user.
>> Brian Holt: So we have our empty option up here that represents all breeds, I don't wanna select a breed at this moment in time so show me all of the breeds.

[00:15:08] And then down here they can select one of the breeds that came back from the API.
>> Brian Holt: Makes sense?
>> Brian Holt: So now this should work.
>> Brian Holt: I'm just going to make sure this works before I say too much, so I'm gonna select dog. And then I go here and notice that this is now enabled, and I can select all the dog breeds down here.

[00:15:38] So dalmatian, and then if I select cat, now there's cats in here, or if I just go back to selecting nothing, then it disables the breed thing again.
>> Brian Holt: Pretty cool, right? I think it's cool.
>> Brian Holt: I don't know what a Peruvian Inca orchid is but it sounds amazing.