 OK, so I've got my app running here. It makes a call to the API. The API comes back with a message, where you just play that message on screen. That's not that useful, so what I want to do is be able to actually submit some data to the API and have it do something with that data. So I'm going to add this form here. Say, give it a form container. And let's just go ahead and I'm using GitHub Copilot. And we're just going to accept some of these suggestions here. And we're not collecting name. We're going to collect the podcast that someone wants to search for. So this is how I would do a form in a normal web app that wasn't using React. But because we're using React, we're going to handle forms a little bit differently. So first, let's just make sure that this is showing up on the screen here. We should already be seeing it, but we're not. Let's figure out what's going on there. There's our form container. So it's in the DOM. Oh, I see, but it's down below. So we've got some default styling here from that Create React app that is causing this app header to show up too big. So let's just go ahead and get rid of that for now. We don't need it. All right, so there's our form. We'll deal with the styling later. But we're asking for a podcast. We've got our input value here. And then we've got our submit button. So that's worked. And the next thing we want to do is keep track of the data that someone is putting into this podcast input field. So we're going to do that by storing it in state. And you can see we're collecting state on this data from the API from our previous example. So we could just copy that convention there. And we're going to say podcast name, set podcast name. So if you're not familiar with setting state in React, this is the variable name for the data we're collecting. And this is the function name that we're going to call to update that value. And this React use state null is the default value we want that to have. So we actually want this to be a string. But right now, just an empty string. That's the default value. If no one were to put anything into this input field, it would just be an empty string. OK, so now in order to update that, we want to add to this input field a function that says on change, call this function, set podcast name, e.target.value. So e is our parameter from this anonymous function here. That's the event variable. It's got a target, which is this field. And the value is whatever is being input into the field. So how do we know that's working? Well, we saw this use effect function from the previous tutorial. And we set that up to run any time the app loads, which is done by using this empty dependencies array here. But we could specify another one of these that does something when podcast name changes. So let's have it just log podcast name, whenever podcast name changes. Now, we should be able to go back into our app here and type. And if you see on my bottom right here, it has changed this every time we change the info in this field, so I can go backwards. And it's updating that state every time. So that's working. Of course, what we want to do is do this when we submit. And I'm going to actually change this to a button. It doesn't need a value, but it does need the text that we want to display, so we'll call it submit. And instead of an action, which is what we do in a normal non-react app, we want to do is say, on submit, handle podcast search. So on submit, we're going to call this function handle podcast search. We obviously don't have that function. So let's add it here. You see it was suggesting what we do, and that it is, in fact, what we want to do. So now that we have that, we don't need this use effect hook to be called every time we update that input field. We just want to know what that value is when we submit. So let's see if that's working. This is one of my favorite podcasts. I'm going to search for it, hit submit, and you see it logs the value once here as 99% visible. So now I want to submit that data to our API and have it do something with it. And I've already got an example of how I'm doing that with fetch here, so we're going to make another fetch request. And it seems to magically know that we want to do that. So I'm going to see what it suggests here. That looks pretty good. I'm going to call the endpoint search for podcast just to be a little more explicit. The method is going to be post. It is going to be JSON. It's going to take that podcast name, which, again, is this state variable here. We'll keep that console log in there for now. And so now we need to make this API endpoint. So go on our back end. Got an example of an API endpoint here. Call this search for pod, podcast. We're just going to log whatever came across in that body. Now, this is not a get request. It's a post request. And in order to process post requests, Express actually needs to load something called express.json. So I'm just going to make sure I add that. And I got to restart my server here because it doesn't automatically refresh like the front end does. Let's see what we get here. It's logging our podcast name on the front end. And it's logging it on the back end. So we know that's working. So the last thing we want to do is actually perform that search. And so we're going to be using an external API. So I'm going to actually be using the open podcast index API. And I have created an account here, a podcast index, and requested an API key. And copy my API key. And I'm going to get their documentation for how to do this in Node.js. Looks like they've got a code sample here. That's great. Now, the first thing I'm going to do is create this environment variables file and create a variable with my API key. And we can access that with this process.emv. What did I call it? And then in order to use that, we actually have to install a package for Express called .env. So .env equals require.env. And to make sure Express can use that, we say .env.config. And now let's see if that is working. It is. I have my API key here. So let's adapt that code sample they gave us. It looks like they want a package called crypto. And in order to do that, I'm going to install it. It's npm. So we just make sure that that was added here to our dependencies. It was. And so I'm just going to copy the rest of this code here. And we're going to copy this code into our search for podcast function. Don't need our console log anymore. Not sure what that is. So we've got, I'm going to convert these to constants. And that crypto library that we required, we can now use to create a hash. We're specifying a SHA-1 algorithm. So now I just add that API key variable. And let me see. And that's the axios.get URL options and response. You actually want to await. This is going to be an asynchronous function call. So we actually need to specify that here in order for this to work. So if we were to try to execute other code below this, and we didn't have that await, we might get our sequences out of whack because this would be taking some time to get a response from the server. But this stuff below it would be executing potentially immediately. So we want to make sure we have that await call in there. So we want to make sure that this whole function is an asynchronous function. So let's see what happens here. If we run this, upper server, restart it, fix whatever issue we got going on here. That, try again, I'll submit. I'm getting an error. My server is not running. That would help. Still getting an error. It's looking for API secret. We don't have that. I didn't paste it in. Start server again. Now we'll try. Submit. And let's see. We got a response from the API. This was our search. And it looks like it didn't bring back any results. So what? I don't have my favorite podcast. Let's just search for a different podcast. Joe Rogan. You got Joe? OK, yeah, they've got Joe. Everybody's got Joe Rogan. So there's a whole bunch of stuff coming back about Joe Rogan, different podcast it looks like. So what we want to do is grab just the relevant data that we need and return it to the front end. So in that case, it looks like we've got this array of feeds here. And each feed has a title and URL. So that's really all I think we need to return to the user. We need to allow them to choose the title of the podcast that they're looking for. And then for our own purposes, we're going to want to know what that feed URL is so that we can go grab all of the episodes from that podcast. So I'm going to set that up. So when we get our data back, we're going to look for response.data.feeds. And then we're going to loop through those feeds. Let's make an episodes array. And we're going to push an object where title is the feed.title, URL is the feed.url. And then we're going to send back to the front end episodes. So let's see if we got that bit right here. Stop the back end, start it up again, refresh, resubmit, Joe Rogan. OK, we've got a list of titles and URLs. So on the front end of our website, where we have this fetch call, right now we're just fetching, but we're not doing anything afterwards. So we need to modify this fetch call in order to receive data back from our API. So we're going to modify this and use the magic of GitHub Copilot to fill out some of this stuff that we need. That's a pretty common format for handling fetch requests. So what we did here is we said, OK, go fetch from our API, wait for the response. When you have the response, turn it into JSON and take the data from that JSON and do a console log on the front end. Catch any errors that you might receive and just console log the errors. So just as a real basic way of handling this, that's how we do that on the front end. So let's resubmit here. I'm getting an error, so something's not running. Whoops, the server's not running. OK, go to submit. See now, we've got our data back. It's got an array of episodes. And each episode has a title and a URL. OK, I think that's a good place to stop for this tutorial. In the next one, we will actually display those results back and work on handling a better pattern for if there's any errors or status messages, loaders, et cetera.