APIs in React Tutorial - Recipe App using React Router

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone we are going to build this recipe application in react so before we dive into it let me just give you a quick demo of how it's going to work essentially it grabs the recipes from an external api so this is what happens when the page first loads and then from there on we can search for recipes so if i type in shrimp it's going to give me the recipes that involve shrimp and then if i type in chicken it's going to give me the recipes that involve chicken from there on we can view the recipe by clicking this view recipe button and then it takes us to that recipe using react router once it's been loaded we can go back to the home page by pressing this go home button and it takes us back to home page again using react router now you may notice that the results that we looked for are still there and this is because we are using data persistence to store our data locally for this project you are expected to have a little bit of knowledge of javascript react and react router okay so without any further ado let's get started alright so to get started i've already created a project folder for you using the createx app cli so inside of this folder i've included the css that i've written for this project which lives right there so feel free to take a look at it and i've also installed the packages that we're going to need for this project so i've installed bootstrap and i've also installed this react write it down packet and these three they already come built into a create react app project okay so i've i will link this project in the video description so go and download it and once you have downloaded it just go ahead and navigate to it in your terminal type in npm install to install the all the packages and the node modules folder and once you've done that just type in npm start or yarn start to launch this project into your web browser okay so come on this is what we're going to start with it's just a blank screen with basically a header and a title that reads recipe search and this is what's going on in this app.js file okay so as you know we're going to type in the values well the names of the recipes to search for them so how do we actually search for recipes well we need the input form so to do that let's just first create a new folder in this source folder and i'm going to name it components within this components folder let's just create a new file and call it form.js all right in there first things first we need to input react from react and then i'm going to create a stateless functional component and i'm going to call it form and it's going to be a stateless functional component because we don't need any state in this component so if a component is a needed state that means we can make it a stateless functional component and not a class-based component all right so i'm just going to implicitly return some jsx so inside of it i'm going to create a form come on and we don't need the action so inside of this form let's just create a new input the type of text let's get rid of this id and the name for now and i'm also going to create a button that says search and before i forget let's just go ahead and export this right here at the bottom so export default form excellent now let's go back to app.js and input this so import form from and then we need to stay in the same directory go into the components directory and then import form all right so let's just render it out right there just below the header so there we go let's go back to the web browser and make sure that it's showing up yes it is so let's just create a method inside of this component and hook it up to this form.js because we need to first make sure that everything is working correctly so i'm going to call this method get recipe and this method is going to be responsible for making the api call okay and let's set it to a arrow function now this syntax may look a bit weird to you you may be used to seeing something like a constructor function and then inside of it you basically type in your methods like this and then you have to hook them up in your constructor function like this dot get recipe equals this dot get recipe dot bind and then you bind in your methods whatever well this has been removed or you can say that deprecated in react-16 so essentially in react-16 you don't really need a constructor function you can even declare your state without a constructor function just like that okay so this is just a neat bit of syntax in the new version of react and i think this is much better and much more practical than the previous versions anyway getting back to the topic first of all let's just console.log something into this method just to make sure that it's working fine so i'm just going to console.log saying working but how do we hook it up to this form component well we first need to go ahead and pass this data to the sum component and how do you pass data to another component you use props so i'm going to name this prop the same as this method so i'm going to say get recipe equals this so this refers to this app component and then this dot get recipe okay press save now back in form we do have access to this get recipe prop because we set it up right there but to access it we can't really use the this dot props approach because this keyword only works in class-based components but this is a stateless functional component which means we have to pass an argument right there called props now with this props refers to these right there so whatever get passed in there gets stored into this argument so this prop is basically an object so to access the properties of an object you type in well props dot and then whatever the name of the property is now in our case we are going to set up an attribute called spawn submit which is a built-in react react attribute and then we can say props dot and then the name of the prop is get recipe so let's just copy it and place it right there excellent press save app.js and now what do we want well we want this console.log to show up as soon as we press this button so now if i open up my developer tools go to the console press search oh what's happening there well keep your keep your eye right about there as soon as i press the search button keep your eye there did you see that that working console log appeared for like just a split second but then it disappears and this is because we are going through a full page refresh this this full page refresh is the default behavior of any web page and to change that all we need to do is we need to pass in an argument e actually let me just convert that to a arrow function first so i don't have to bind it so this e is basically the event object in javascript this is nothing specific to react so since this is an object means we can access the properties of this object so i can say e dot prevent default and this method is going to prevent the default behavior of this web page which is what that is going to refresh so now if i press save go back to the web browser press search we can see that the working console log is showing up brilliant okay well what do we need to do next well we need to first let's just let's just um make sure that we are actually reading the values that we type in there so first of all we need to set up a name attribute because this is what we're going to use to read the values from the input okay so name and i'm gonna name it recipe or let's just call it recipe name okay i'm gonna copy this and within this get recipe method i'm going to create a new constant and i'm going to call it same as that recipe name equals so again this event object means we can read the properties from it so e dot target dot elements and then what do we need to access well we need to access this name attribute so what's the name of this name attribute it's recipe name so e dot target.elements.name dot recipe name and then what do we need to access from it we need to access its value so doc value okay now instead of console logging this working string let's just actually console.log this recipe name constant that we just created right so let's go back to the web browser and type in anything type in chicken press search and there we go this is working just fine okay now let's get into some more interesting stuff we need to make an api call to a website and then we are reading the data from the website and showing up to our web application and what's the website that we need to make the api call to well is this recipe api called food to fork that's kind of a weird name but food to fork dot com slash about slash api now you can read this but for the most part all you need to do is you first need to sign up for the website it's completely free and you need to obtain an api key because you need that in order to work with their data essentially an api key is a way for websites to know who you are and what kind of data you're trying to access so they they use your api key that are associated to your email address and then they just basically want to know what kind of data you're trying to access that's the whole purpose of obtaining the api keys okay so all you need to do is just press the sign o button and then it will redirect you back to this page once you have got your api key so the url that we need to make the api call to lives right there now see this is the url that we need and see this key parameter right there this is where your api key should go so once you have done that your url should look something like this right there see this is the exact same api right there sorry this is the exact same url apart from the fact that this api key variable has been replaced by my actual api key so all i did was i first signed up then i copied this url i pasted it right there and then instead of this api key wrapped within those curly braces i just pasted my api key right there and what i've been looking for by default we are looking for this shredded chicken and these are the results that we are getting back and you may also notice that there's also this count parameter right there and we can change that we will do that later on in the video but we can change that to anything we can change that to 5 10 15 whatever you like it just depends on how many results you want to show so in this case the count is set to five which means we are getting an array of recipes and this array has five different objects and then you see that these are the properties that we're going to read in order to access the data so this publisher title recipe id just some of these we're going to use in our web application okay so let's actually go ahead and copy this url okay go back to our application and i'm actually going to just go ahead and create a new constant but all i'm going to do there is i'm first going to extract my api key because i'm going to store that in a new constant so there we go because it's always a good practice to just store your important data into your own constants in case you need it later on okay and i'm just going to go ahead and create a new string and paste my api key right there okay so once that's been done we are now ready to make the http call to this url right there so to do that i'm first going to go ahead and put this link out just like that and inside of this get recipe method just below this prevent default call i'm gonna create a new constant and i'm gonna call it api underscore call and for now i'm just going to go ahead and initialize a string and inside of that i'm going to paste this link right there that doesn't seem right let's just fix that there we go okay so we're gonna make use of something called async await and the fetch api to make the call to this link right there so how do you initialize a async await function or in this case how do we make this method asynchronous well just before we declare the method we're going to type the keywords async okay and then right there we're making the api call we type in the keyword of eight and to actually make the http call we're gonna use the fetch api so to do that i'm again going to go ahead and cut this link out and i'm going to type in the keyword fetch and within that instead of initializing the string i'm going to use the es6 template literals so to do that is just using the backticks and then i'm going to paste the link right there so we need to change a couple of things now because remember we have our api key stored in this constant right there so in es6 template literals we are allowed to inject the variables inside our string so to do that we're going to go ahead and copy this api key constant and we're going to inject it right there where the key is required so to insert a template neutral all you do is you type in the dollar sign and then a couple of uh curly braces and then whatever goes inside of these curly braces it basically what we want to do so in this case we just want to inject this api key variable so again i'm just going to go ahead and copy this and paste it right there and what do we need to do next well the default search for now is just shredded chicken right there later on we will change that to whatever we type into our form but for now let's just leave it to shredded chicken okay so i'm actually going to get rid of this console log right there because we don't need that anymore so this is just making the api call it's it's not actually grabbing any kind of data so to do that i'm actually going to create a new constant and i'm going to call it results or let's just call it data and we're going to set it to the return value of this fetch function right there so again to grab the value we're going to first type the keyword await okay and then we also need to convert this whatever we get back from this api to a json format so you may be used to seeing something like you know json.parse or json.stringify but what's how clean this is in fetch api all you need to do is you need to type in the contents name which in our case is api call and then we just call the json method there we go just like so okay so now whatever we get back from the api is going to be stored in this data constant right there so let's just check what's inside of this data constant so if i console console.log this data object now remember this method is going to fire as soon as we press this button right there so now let's just go back to our application and press search what's that no access control allow origin some websites do not allow local servers to access their data now in our case we are using our localhost 3000 to access the data from this food to fork website so we need to do something to trick this food to fork servers into thinking that we are a legitimate website so in other in other words we are live on the servers so how do we fix that well there's a very handy tool for that it's called course anywhere.heroku.com so all we need to do is we need to go ahead and copy this url okay and go back to our application and just before our link begins we just prefix it with this url that we just copied right there all this is going to do is it's going to trick this website into thinking that our server which in our case is localhost this is actually a live server that lives somewhere on the internet okay that's all this url is going to do so now if i press save and then go back to our application press it and hopefully this should give us some sort of data and yes it does so this essentially is an object and the value of that is this data constant right there so if i expand it this is the count so remember we get an array of five objects because we have set the count to five so if i change the count to let's say 10. let's see what we get back so press search and there we go we get an array of 10 objects so let's just go ahead and crack open this recipe array and let's take a look at what's inside of this well it's basically like i said it's an array and inside of that is just a count of objects so that count is what we type in right there so let's just crack open the first one so these are just a bunch of properties that we're going to use in order to display the data on our website so what do we need here well to actually access this data what we need to do is we need to drill down into this array first this recipes array so we're going to have to say something like data so remember data is this whole object so to drill down into recipes we have to say data dot recipes and now if i console log this we get back the array that we need so this is the array and let's just say that we want to go to this first element in this array so i can say data so again to access a number in an array you use the index in this case it's zero so we want to access the first element and inside of this and inside of that let's just try and access this recipe id so let's just copy that and paste it right there and let's see what we get back so press search and there we go we get the recipe id back but this isn't what we want we actually want to display the data on our actual web page which is this whole thing right there so how do we do that well let's take a look so to actually display this piece of data we don't really have anywhere to store that inside of so we do have this constant called data but this only exists inside of this method so now would be a good time to introduce state within our application so to do that it's just going to type in the keyword state and i'm just gonna set it to an empty object now again you might be used to doing something like typing in a constructor and then declaring your state like that but like i said in react 16 and further on you don't need the constructor function at all so you can just delete that all together and what you can do is you can just simply declare your state like that so what kind of state do we want to trace what we want to do is we want to set up an array which is going to store whatever we get back from the api and what do we get back we get back an array so to do that let's just create a first piece of state called recipes and set it to an empty array excellent now how do we actually make use of this state right there well instead of console logging this piece of data right there let's just do something else let's just use the built-in set state method to set this piece of data to this recipes array so to do that i'm just going to say this dot set state and it's going to take an object and within there we want to grab the recipe state and we want to set it to data just like that okay so now instead of console logging once we get back from this data let's console log this piece of state right there so console.log and this dot state dot recipes okay let's go back to the web browser open up our console press search and we should get back our piece of state and that we do and inside of this piece of state we have an object and then inside of the object uh is this recipes array right there so all we want to do right there is we only want this array right there so to do that let's just say data dot and then is this recipes array right there because we want to set this recipes array to this recipes area right there okay so data dot recipes there we go go back to the web browser press search and now all we get back is an array and within that array there's just a bunch of objects so this is all well and good but how do we actually display this data onto our actual screen so to do that let's just do something more interesting for now all i'm going to do is i'm going to open up a javascript expression right there which means and by the way in jsx opening up a pair of curly braces means that you want to inject something that is related to javascript okay so to do that i'm going to make use of an array method called map now map is a new method that was introduced in a later version of javascript and essentially it allows you to go through each element inside of an array and then you can manipulate it you can change it anything you want to do with it so it's kind of like the for each method but in gsx we can't really use the for loop or the for each loop so we're gonna have to make do with what we have so what we have here is the array method uh array.map method so in this case the recipe state is an array so all we can do is we can say this dot state dot recipes and then we call in the method called map and this method takes a callback function so let's just give it a callback function and we also give it a argument right there an argument i should say or a parameter and this parameter is going to contain each of the elements that are inside of this recipes array once the state has been set so let's just call it a individual recipes just like that and then within there let's just return a paragraph that says and again since we're going to make use of this javascript thing inside of this jsx paragraph tags we have to introduce curly braces so what do we want to access well for now let's just say recipe and then let's just crack open one of these and recipe.title for now let's just console let's just print out recipe.title so remember it's going to print out 10 different titles on the screen because it's going to loop through each of these elements right there and the number of them is 10 so we're going to get 10 titles printing out to the screen okay so again press save go back to the web browser there are no errors which is good so now if i press search i should get some titles onto the screen yes we do this is brilliant but we also have an error it reads each child in an array or iterator should have a unique key prop and this error is something to do with react essentially it's asking us to set a parameter called key to each of these elements that have been looped over and the reason for this is that react wants to know what each of these elements are i mean there is no way for react to know what this title is what this title is all it's doing is it's reading the properties of each of the objects right there but it also needs to know that in future in case we need to manipulate any of these so react can just grab the key prop and then from there it can do its thing so to do that all i'm going to do is i'm going to set this recipe id which is this right there i can also set the title or the search url as long as it's something unique and different to compared to the other objects it will do but just for the sake of simplicity i'm gonna copy this and i'm gonna say that key equals and again i'm gonna have to open up a javascript expression and inside of this i'm gonna say recipe dot recipe underscore id now if i press save and go back to the web browser press search we can see that all the titles are printing out to the screen and we also don't have any errors uh this is just a eslint complaining that recipe name has been declared but it's not been used and this isn't really something to worry about so let's just move on so currently we are just getting the default value which is this shredded chicken right there but what we want to do is we want to get the results of whatever the user types into this input form right there so to change that we already have a value from that form which we grabbed earlier on using the event object so all we can do is we can use this recipe name constant and like i said this is a template string so we can actually inject this variable right there instead of this shredded chicken so what i can do is i can just cut this out okay and then to open up a template literal you type in the dollar sign followed by a pair of curly braces and then within there we can inject this variable right there just like that okay press save go back to the web browser and now if we type in let's say shrimp press search and we are indeed getting the results that involve shrimp on the screen as well as in the console right there okay so what's next so let's actually grab a bit more than just the titles so if i just crack open one of these objects right there uh we can use a bunch of properties there so what we're gonna use is we're gonna use this title which we already use and we're also gonna use this publisher name and we're also gonna use this image url but for now let's just throw in this image and see how it goes so i'm just going to go ahead and copy this i'm going to go back to our application and instead of just returning this one single paragraph let's actually just cut it out open up a pair of parentheses and inside of it let's create a div throw in that paragraph tag and let's also add in a image tag just above this paragraph sag so and the source is going to be actually this recipe dot and then the image url so as always to open up a javascript expression you have to throw in a pair of curly braces and then recipe and then image url so what kind of description do we need to give it to this image tag well we can just throw in the title there just like we did right there so we can say again to initialize a javascript expression come on we have to first open up a pair of curly braces and then recipe dot title excellent now if we go back to the web browser and press search let's look for pizza this time and we should get back the images they look hideous at the moment but we will fix that so why is this giving an error again uh this key prop error even though we have already passed the key right there well the error here is that the key has to be passed within the most parent element so what's the most parent element in this case well it's this div right there so i'm just going to cut this out and paste it right there just like that so now if you go back to our application press pizza and yeah it's working out fine but it's looking rather hideous at the moment so we're gonna fix that next so to do that we're gonna make use of bootstrap which i already have included in our package.json and as well as our index.js file right there so to make use of bootstrap we're just going to add a bunch of classes from the bootstrap framework but before we do that let's take care of this piece of code right there all we are doing there is we are mapping over this piece of state right there but this is a bit messy i mean we don't want to do that in our app component so to take care of that let's just transfer this into its own component so what i'm going to do is i'm going to create a new component in the components folder and i'm going to call it recipes.js okay once i'm in there it's gonna import react from react after that let's just create a stateless functional component because again we don't need any state in there so we can make this a stateless functional component so to do that i'm just gonna call it recipes and i'm going to set it equal to an error function and i'm going to implicitly return some jsx so first of all i'm just going to return it div and within this step for now let's just type in recipes just to make sure that it's working and right there let's just export defaults at the bottom excellent now let's go back to our app.js file and just underneath this form component let's import the recipe so import recipes from and then it's the components directory and then recipes okay so i'm actually going to cut this out and i'm just going to go ahead and render out a recipes component press save go back to the web browser and we do have our recipes component showing up okay but we don't want it to just render out this text we wanted to actually display the data that we were previously getting so how do we do that well first of all we need to pass this state this recipes array to this recipes component and then in this inside of this recipes component that is where we're going to map over that piece of state right there so how do we pass this piece of state to our recipes components well as always to pass anything inside of react you have to use props so to do that i'm just gonna pass a new props and i'm gonna call it recipes okay and and i'm going to set it to this dot state dot recipes excellent so now this prop means that we do have access to our recipe stage that lives there so now back in recipes.js file to get access to this prop right there we first need to pass in an argument right there called props because this is the only way we can access the props we can't really say something like this dot props dot whatever because this keyword will not work inside of this jsl that lives inside of this error function okay if it was a class-based component then we could have used it but in stateless functional components there's no way we can access the props using these keywords okay so now how do we proceed with our recipes props well it's the same as what we did right there so i'm actually just going to paste the piece of code that i copied that i cut earlier and all i'm going to do with in there is i'm going to get rid of this keyword and i'm also going to get rid of this state because the state does not exist in this component instead i'm going to type in props and what's the name of the prop is this recipe so props dot recipes and then is the exact same thing that we have been following so again let's just break it down we passed the props property uh you passed the props argument that props argument has access to this recipes prop right there and then inside of this inside of this div all we are doing is we are mapping over this piece of state right there and this gets filled once this search recipe button gets called okay and then once that's been called that means that this this prop has access to this piece of state right there which means we can actually map over inside of another component and that component right now is this recipes components okay a lot of talking now let's save the file go back to the web browser and see if that works let's just open up the console and let's look for chicken press search and we are indeed getting back 10 different values sorry 10 different recipes for the chicken and this is brilliant so now that we have taken care of this recipes component let's go ahead and actually style our application because it it looks very ugly right now so let's continue with that so when i say styling i mean that i'm just gonna add a bunch of css properties that i've already declared inside of this app.css file so if something doesn't make sense to you then i've named these classes very appropriately so just have a look at this file and it should make everything clear to you and like i said before i've already installed bootstrap into this project as well and this is being imported right there inside of this index.js file and we're gonna make use of bootstrap as well okay so we're not really gonna make any changes to this app.js file instead let's just first open up this form.js file and this is where we're gonna get started with our styling okay so the first thing that i'm gonna do here is i'm gonna add a style attribute right there and this takes a javascript expression and then inside of it you can declare declare an object and then there you can define your styles so the first thing that i'm going to do is i'm going to declare a margin button okay and i'm going to set it to to ram okay now next step i'm gonna do is press save and i'm gonna give this input a class name of form underscore underscore input copy that and i'm going to give this button a class name of form underscore underscore button brilliant let's just go back to our application now and we can see that those styles are being applied okay now for the main styling we're going to stay in this recipes.js file so right now it's very simple but we're gonna completely transform this structure right there so what i'm gonna do is i'm actually going to go ahead and put this whole thing out just like that so start with the div okay so this div is gonna act as a bootstrap container okay and inside of this div let's just throw in a row okay now next up what do we need to do well this is where we are going to throw in our map function okay so to do that let's just let me just take a look at what i'm doing here because this tutorial is not scripted so i just really need to be careful with the classes so i don't mess anything up anyway so i need to add the bootstrap columns so what would be the best place to do that well this is one individual div that's being rendered out to the web browser so that means this would be an ideal place to throw in the bootstrap column class okay so to do that i'm actually going to cut this whole thing out just like that create a new class and i'm going to call it call md-4 excellent so now let's just go ahead and open up this div and inside of this div let's also throw in an other class name and call it recipe underscore underscore box brilliant okay let's carry on and what do we need to do next well seeing as we are mapping over we are throwing in this div inside of this map function that means we get we have access to every property that this recipe has so the first thing that we're going to do is we're going to throw in an image tag and the source is going to be again recipe dot i believe it was image underscore url and the alt was recipe underscore the recipe dots i believe it was title yes it was okay what's next well let's also give this image a class so i'm going to say class name and i'm going to set it equal to recipe underscore underscore box and then it's img let's just break these attributes down to their own lines just so it's a bit more clear okay let's indent that in let's get rid of that there okay so what's next well after the image stack let's just go ahead and underneath this image tag let's open up a div and call it recipe underscore underscore text okay inside there what are we doing well let's open up a javascript expression because this is where we're going to throw out our recipe title so let's just say recipe dot title okay and let's wrap this inside of a h5 tag just so it looks like so it actually looks like a title so recipe come on on this recipe.title okay let's just take a look at how it's looking like so far well it says rvc is not defined so line number 12 and yep of course it's not defined so press save and go back to the web browser let's just close that for now and press pizza search and see what we got back well we are getting stuff back but it's not looking very promising at the moment so let's just go ahead and fix this so the source for this tag is of course this image url so i typed in img anyway let's take a look at it now so pizza search and this is looking much better now okay well what is next well let's also grab another property from this array called publisher okay this one right there and again it's complaining about that key prop and we will pass that in a moment in fact let's just do it right now so what's the most parent div is this component right there so sorry this div right there so let's just say the key equals recipe dot title and that should fix it and while i'm here let's also give this each of the columns a bit of spacing towards the bottom so i'm going to say style equals and then an object that says margin bottom is let's just give it to ram okay press save so what is next well we were going to throw in the publisher so to do that let's just um shall we throw in a paragraph tag right there yeah staying inside of this div let's just throw in a paragraph tag and give it a class of recipes underscore underscore title and let's also copy this class and paste it right there and this should be title and this should be subtitle okay so let's open let's just type in publisher so this shows up and then let's throw that in a span tag so span and then inside of this pen what do we need to do well let's just open up a javascript expression and type in recipe dot publisher okay so what is next so we're also going to add a button which we can click and then we get taken to the recipe and we will hook that up using react router later on but for now let's just go ahead and add it so below this come on this recipe underscore text div let's just open up a a button tag okay and call it for now let's just call it view recipe and give it a class of recipe underscore underscore button brilliant now let's go back to our application and this should look the way we want it to look okay it's looking promising for the most part but i still kind of don't like the way it's looking so i probably mistyped something so i think the class name is recipe buttons actually it is and this should be recipe text and it should be recipe this should be recipes box okay my mistake okay let's go back to our application again press search okay this is looking good but again it's not perfect and i'm pretty sure that i'm typing out the class names somewhere wrong so it's recipe underscore underscore buttons actually i think i just typed one underscore right there so now if i press search there we go this is looking much better now so see i don't like how some of these boxes are longer in height and some are small in height so let's just type in something else so chicken see notice that you know when the name gets longer the box itself gets longer as well so how do we fix that well let's just make use of something inside of something very handy inside of javascript so to do that we're gonna do this inside of this recipe title so we're gonna make use of a javascript method called substring so it's better to explain it while we do it so let's just open up let's just expand this h5 tag right there let's put that in a separate line and right there what we're gonna do is we're gonna say if recipes dot title okay so dot length so remember this is a string and strings in javascript have a property called length so we can check that if recipe or title dot length is smaller than 20 okay so we're using the ternary operator right there so it kind of works like if else statement but we can't really use if else statements inside of jsx so we're gonna have to make do with the ternary operator okay so if recipe title dot length is smaller than 20 then this question mark refers the then clause inside of the if else statement then what we want to do is we want to open up a template string and inside of it we're just going to render out a recipe oops that's not how it should be it should be like that we're going to render out just the recipe or title as it is so if that the length of the title is less than 20 characters then we are just going to render out the recipe title just as it is okay else so this colon stands for else so if this condition isn't true then this is what's going to happen so else let's open up a template string again else recipe dot title dot and this is where we're going to make use of the substring method inside of javascript okay so this essentially takes a couple of arguments the first one is where it's going to start and the second one is where we want our string to trim so if the length of the title is smaller than 20 characters that means it can fix inside of just one box if it's greater than 20 characters which this one is what we can do is we can cut it down to just 25 characters so to do that we need to start with the first index the so the first letter which is right there and the index of that is zero so zero and then we just want to trim it down to 25 characters so this is what the second argument is going to be okay so once it's been done once the character has been trimmed let's also give the user some kind of feedback that this string is longer than it's appearing out to be so to do that let's just type in three dots right there okay go back to the web browser again search for chicken press set and now we can see that the titles that are longer than 20 characters have this kind of a nice you know three ellipses showing up right there and those titles that are smaller than 20 characters they're just showing in their full length and this is exactly what we wanted to do okay so let's continue okay so now we're gonna add react router to our application more specifically we're gonna make this view recipe button work okay so to do that we're obviously gonna need react router and i did tell you earlier that i already have installed the react router packet so which lives right there okay so what we're going to do for that is we're going to create a new component inside of this components folder and we're going to call it router.js this component is ultimately going to replace this app component which lives which currently lives inside of this index.js file and this is what we're going to render out to the web browser okay so what do we actually need inside of this router components well obviously we need react so import react from react and we're also going to grab a bunch of named exports from this react write down package so we're gonna grab in fact let's just um first say import and then react router dom and then we can type in the property so we need browser router we need switch and we also need what do we need route okay if you are new to react router then i highly recommend you first learn about react router and i do have a video for that on my channel so go check that out it will give you a basic idea of react router and how it works okay so now you may notice that this new update in vs code it basically doesn't give you any highlighting unless you use the variables that you are using in your application so let's say that this reacts it's it's not highlighted it's usually in colors and the reason is appearing this dim is because we haven't used it yet so this is a nice way of vs code or to you know tell you that this is the stuff that you haven't used yet so use it okay so now if i just create a new component and i'm going to call it router and i'm going to set it to a stateless functional component and let's just make it return some jsx so now as soon as i create this div you can see that this line gets highlighted and this is because react has uh and this is because vs code has told us that you know this this thing right there has been used but we haven't used any of these properties yet so this is why they are still appearing gray okay coming back to the topic so we don't actually need this div what we're gonna do is we're gonna wrap everything inside of this browser router so i'm gonna place it right there and inside of it what do we need well we need our routes so to throw in our routes we just type in route and it's a self-closing tag and inside of it we add a component attribute and we also add a i believe is path yeah but i think that comes before the component so path equals and anything that that goes inside of it okay so how are we going to structure this well for the home component which obviously gets represented by this forward slash so if the path is this forward slash then we are going to show up our app.js components so app.js is obviously this whole thing right there so to do that we first need to import our app component so import up from and then we need to jump up our directory and then this app so if the compo if the path is this forward slash then show us this app component and we're also going to add a new route and that route is going to be that individual recipe whatever we click on so we don't really have any component for that yet but for the time being let's just create a new component and call it recipe now pay attention this is recipe and this is just an individual recipe okay it's very easy to make mistakes so just pay attention right there create a new components input react from react and then just create a stateless function component for now anyway and let's call it recipe and set it to another function and let's just implicitly return some jsx okay dev and let's just type in recipe component and export this right here at the bottom so export defaults recipe excellent now we need to actually input this into our router because this is what we're going to use in order to render it out so import recipe from and then it's in the same directory so recipe right there okay i'm just going to duplicate this line and i'm going to say that if so what what path do we need well it's going to be a bit more complicated than what we're used to but for now let's just throw in the path recipe so if the path is forward slash forward slash recipe then render out this recipe component okay well currently it's not going to work because this router file only exists in our components folder and we actually need to make use of it so to make use of it let's just go back to our index.js file and let's completely trash this app component right there and instead let's import i believe it's router from and then i think it's in the components folder and then router okay so now instead of this app component we're going to make use of this router component right there okay press save go back to the web browser and it says export defaults imported as router was not found and i know what the mistake is back in writing yes we need to make use of this switch statement right there so to do that let's just type switch and then throw in our routes and i also forgot to export this so export defaults and then router so now if i go back to the web browser we can see that we have our app component in all its glory and we can still search for recipes so if i type in chicken i can get the results that involve chicken and then right there what comp what other path did we create we created this recipe path so if i type in forward slash recipe i don't get recipe and this is because react router can be a huge dick at times so to fix that all we need to do is we need to give in the keyword exact right there to the topmost component what this is going to do is it's going to make sure that only render out this app components when this path is exactly this forward slash and there's there is nothing else in front of it so now if you press save go back to the web browser we can see that we are indeed on this recipe path and we are getting this recipe component render out to our application okay so now let's actually make the button work so what i mean is you know this person right there let's actually make this work so when we press it we actually get taken to the recipe okay so to do that it's going to be a bit more complicated than what we're used to but let's give it a go so back in this router.js file we don't really want this static recipe path what we want is we want a path parameter or in other words it's also called a route parameter so to start error parameter you type in colon and then anything that goes after it is considered as a parameter or a variable so what do we need in this case well you can name it anything but we're gonna grab the recipe id to access the data of the recipe so for the sake of simplicity and relevance let's just type in id okay now this path will only work so if i just simply go to recipe it's not going to work so forward slash recipe you can see that it's not going to work and this is because it also it's also going to take a route parameter so if i type anything after that let's say if i type in one then we can see that the recipe component is indeed showing up okay so this is how it's going to work so what's next well you know this button this view recipe button this lives inside of this recipes.js file which is this thing right there so to make to make this work we're going to grab another named export from the react write down packets and let's just type it in first come on and this package is called well this is a named export indeed and this is called link now this link essentially works the same as the anchor tag in html all it does is it directs you to whatever link it is you know pointing at so to do that let's just first go ahead and split this button into multiple lines and what i'm going to do is i'm going to cook this this new recipe text and there i'm just going to go ahead and throw in this view recipe and convert this to a link it's not going to do anything just yet but let's just go ahead and press save go back to the web browser search for the recipes and our application breaks this is because we need to specify a two attribute to this this link right there so essentially it's the same as saying so you know two is basically telling it what path does it need to go to so in our application we have two paths so what we're doing here is we need we need to tell this link to which of these two paths to go to once it's been clicked so now obviously we need to go to this recipe forward slash id and now remember this is a parameter so anything that goes in there gets gets replaced by this id parameter okay so we're actually going to make use of template strings right there because we need to inject some variables so to do that how do we do that because the template strings don't really seem to be working well to fix this all we need to do is we need to open up a javascript expression and then inside of it we need to open up a object and then we type in path name now this is where we're going to assign the path so if the path is and and let's set it to tempo literals because remember inside of a javascript express inside of a javascript expression we can use the template rituals so if the path is forward slash recipe now again this is id so that means we need to grab the id of the recipe so remember we are in fact mapping over the the whole recipes array right there so to grab the recipes all we need to do is forward slash recipes and then remember we can inject the variables so to throw in the recipe id we can just say that recipe so remember this recipe is referring to this recipe argument right there so recipe dot and then the properties that we need is called come on it's not there recipe underscore id okay and now how do we actually proceed with that i mean yes we do have this path provided so if i go back to the web browser press search and you can see that this has indeed been convert it to a link so now if i hover over it i get this you know hand sign and then it's showing me that it's actually a link so let's see what happens when we press this button the recipe boom we do indeed get taken so remember this is the recipe this is the recipe id and once we hit it we get taken to this recipe route right there so now if we choose a different recipe let's say we click on that we can see that the recipe id has been changed because the recipe id is just a number and that is what we're using to throw into our url does that make sense well i hope it does okay so what's next well how do we actually access the data inside of this recipe.js file first of all we need to convert this to a class-based component because we're going to use some of the properties that are only available inside of the class based component so to do that class recipe extends react dot component excellent let's just open up a pair of curly braces type in render and return some jsx so for now let's just return again the recipe component okay press search go back to the web browser make sure everything is working fine yes it is okay so if we didn't know any better we wouldn't know that what's going on inside of this recipe component but we do indeed have access to props right so if i type in console.log and then just props so we all we're doing here is we're just console logging the props so as soon as this component is loaded it says props is not defined and this is because we need to lock this dot props okay go back to the web browser open up the console so there we go and we do indeed have an object so if i expand it this is just a lot of react writer stuff that's been bound to this recipe component because we specified it right there in this recipes.js file so the reason we are getting all this react writer stuff is because we created a link right there and then this link belongs to react router so that means it's been bound to this recipe component as well okay so now if we go ahead and take a look at it we can see that we have a location object and if i expand it this is the path name that we set right there in recipes.js file this thing right there okay and we also have another property called state and this is what we're going to use in order to display the actual recipe onto this recipe component so to do that what are we gonna do well back in this recipes.js file we are gonna create an other attribute inside of this object right there so right after this string ends actually let me just break it down to a new line so path name and then i believe it's that one right there and this one is going to be called state okay now this state is going to contain a another object and the name of the object is gonna be recipe okay and let's just call it now like i said we're gonna use the recipe title in order to display the data so to see to do that let's just say recipe dots and then title and we do have access to this recipe because we are mapping over a recipe array and then we are setting up this recipe argument right there press save go back to the web browser and again expand this object and if i refresh it we can see that the state is still undefined and this is because the state is only going to get calls when we press this button now in this case this page is merely getting refreshed it's not we are not coming here because the button has been pressed so the state is only going to get set once we actually press the button so now if i go back all the way to my app component and again we type in chicken press search just go to any recipe let's just try that one and now if i open up my console we can see we have an object and there we do have a state object and inside of it we have the title which is called well whatever it was called chicken pyramidian i don't know what it is but anyway the good news is that we can use this state to display the data onto this recipe application okay so let's just do that now so back in this recipe.js file there is a reason why i set this up as a class-based component and the reason is that we're going to make use of state inside of this component okay so first of all let's just go ahead and declare our state and the state is going to be called active recipe and for now let's just set it to an empty array okay well next uh what's next well we're gonna make use of a react built-in method or in other words called a life cycle hook called component did mount this method is going to get fired as soon as this component gets loaded or gets mounted onto the web browser so anything that happens inside of it it's going to happen as soon as this component loads on the screen okay and we're actually going to do something pretty similar to what we did in app.js so for the most part what i'm going to do is i'm just going to go ahead and copy everything that's inside of this skip recipe method and we're just gonna change a few things for now let's just paste them and we also need our api key okay copy this go back to the recipe component and paste it right there so what exactly are we going to change well there is no recipe name in this component because obviously there is no form so what i'm going to do is i'm going to go ahead and delete this and i'm gonna instead type in title because the title is what we're gonna grab in order to display the data so title is what what do we equal it to we have an object there right so this dot props and then it's location so this dot prop shot location and then location.state and then the property is called recipe and remember we are getting this because back in recipes.js file we set up the state and then state the recipe okay so this the location actually is this dot crops location and then it's state and then it's recipe excellent so now what we need to do is we need to replace this recipe name with this title right there because this recipe name constant does not exist anymore and we can also get rid of this count okay so we can get rid of that and i'm just going to copy this and i'm going to paste it right there and we don't need this e dot prevent default because there is no form right there so we can just go ahead and get rid of that as well right so next up let's just change uh the names of these two constants because they already exist inside of this app.js file and it's not going to make a difference but it's best not to have any duplicates so i'm going to change this to rec or request and i'm going to change that to res or results or response whatever you want to call it and let's just get rid of these two statements right there and for now let's just console log this res right there all right so press save go back to the web browser and it says that api call is not defined and line number 13. so let's take a look at what's going wrong all right of course we need to change this to rec okay press save go back to the web browser and we are on the recipe component and there we go we do have a count showing up but it's actually 18 recipes it's giving us and the reason for this is because the recipe that we clicked on maybe has more than one name so you know it's cashew and chicken pasta you can see there's quite a few of these so to fix that the the most relevant recipe is going to be the topmost recipe in the array in this case the index is zero so instead of grabbing everything that's inside of this um recipes array what we can do is we can say red so remember res is this whole object so rest.recipes and then we just need to grab the first element in the array so in this case we're going to grab the element with the index of zero okay press save go back to the web browser and now we can see that we're only getting the recipe with this id that we searched for which is four six double line six and this is the title and these are all the images and you know the publisher that we're going to use to display the data okay brilliant so what's next so now we're going to make use of this active recipe state right there to actually display the data onto our actual screen okay so to do that let's just type let's just get rid of this console log right there for now and instead just type in this dot set state and then it's going to take an object and then we're going to assign the active recipe state the exact same thing that we will that we were console logging earlier so that was res that recipe and then the first index inside of it okay press save and now instead of console logging the res object let's just console log the actual state so this dot state dot active recipe press save go back to the web browser and we should still get back the same thing but beyond so let's take a look why so it says oh actually it should be recipes okay now this should work let's go back to the web browser and yes we are indeed getting back the same thing okay so now how do we use this piece of state to actually display the data onto our actual you know this whole screen right there well let's just add a bit obstructed inside of this render method so i'm actually gonna get rid of this whole thing and you're just gonna have to watch me type a bunch of you know markup using the using the classes and some of the bootstrap classes so the first one we're gonna start off with is called container and this is going to act as the wrapper div and then inside of container what we're going to do is i think the next class that comes is a because we we don't need to add a row because in this case we aren't really throwing in any columns all we need is just a big image and then underneath that just the title and the publisher and that's it so we don't really need to add any rows or anything so what i'm going to do is i'm just going to throw in a custom class that i've written and this is called active dash recipe okay let's crack open this and inside of it we're going to grab the image so remember we do have access to all these properties just like we did in app.js file so in this image tag i'm going to give it a class of i believe is active recipe underscore underscore image and then the source is going to be now see if we type in this dot state dot active recipe and then you know grab all these values this is going to get a bit messy i mean we're gonna have to do this for the title we're gonna have to do this for um for the publisher for the website so an easy way to fix this is to actually store that into a constant so just above this return statement what we can do is we can create a new constant and we can call it recipe and then we can set it to this dot state dot active recipe okay so now instead of typing out this whole thing we can just copy this and we can paste it right there and now that's all we need to type in order to grab the values of the object okay so now recipe starts and then it's image underscore url and for the alt tag let's just give it recipe dot title excellent press save let's take a look at what's going on in the web browser and there we go we do have the image showing up and this is brilliant so that means everything is working fine so let's move on okay so right below this image tag i'm gonna throw in a h3 title tag and i'm gonna give it a class name of i think it's i'm just gonna head go ahead and copy this active recipe because this is the prefix to every class name and then the prefix is title okay and the title is obviously going to be recipe dot title okay moving on let's add a h4 in there and i'm going to give this a class name of i think it's rest active recipe and then we're going to also grab this publisher because you know we're just going to show that who actually created this recipe so we're going to grab this publisher property so i'm just going to go ahead and copy this whole thing and paste it right there and i'm going to replace this title with i think is publisher yep okay and within there let's just throw in actually let's just break this into a multiple line because we're also going to throw in a span tag so let's type in publisher and then open up a span tag and then inside of it i'm just going to add a i'm just going to grab the property so recipe.publisher okay brilliant so what's next well uh just below this uh h4 tag let's throw in a paragraph tag and give it a class name of i'm just going to go ahead and copy this active recipe underscore underscore and this is going to be the website of the publisher so in this case we're going to grab come on where is the website so publisher publisher url recipe id title i think it's this one right there search url yep that's it oh publisher url actually this one right there so this is the property that we're gonna grab in order to let users know that you know this is the website of this recipe creator so again we're going to break this down to a multiple a new line and i'm just going to type in the word website right there add in a colon and then right there i'm going to type in a span and i'm going to give that inside of it it's going to be an anchor tag because obviously we need to redraw it we need to redirect our users to their website so the hrav is going to be so what is it recipe.publisher publisher url okay recipe.publisher and then underscore url and within there let's just uh type in the uh exact same thing so i'm actually just going to go ahead and copy this and paste it right there because we're actually going to display the website onto the screen as well right so the last thing that we need in there is the actual button that we are going to go ahead and create now so button and this is going to be responsible for taking us back to the home page so let's just give it a class name of and i'm just gonna go ahead and copy this active recipe thing paste it right there and then it's called button okay and let's just type in go home brilliant press save go back to the web browser and we should have our desired desired results yes we do okay so now you may notice that before the page loads this whole blank thing is showing up right there and we don't want that so what do we do to change that well let's just make a check we can check that if the uh because you know since all these values are coming from the state so we can just make a simple check that if this state has a length of zero then we don't want to display anything because if it's zero that means that this array is empty this active recipe state is empty which means that nothing is inside of it so as soon as it it gets filled we can actually display our data okay so to do that i'm actually going to cut out everything that's inside of this active recipe div and open up a javascript expression and inside of it i'm just going to type so we're going to make use of the and operator so as you know for the and operator both of the conditions have to be true in order for something to execute okay so we can say that this dot state dot active recipe and then since it's an array we can grab the length property and we can check that if this is not equal to zero so again if anything is inside of this array the length is going to be greater than zero so if this dot state dot active recipes length is not equal to zero only then do we want to render out everything that that's inside of this div that we just cut out so there we go we are making use of the and operator and now we can just go ahead and paste our div right there excellent so i'm just going to indent some of this stuff in just like that actually this should be there and then this should be there okay now if we go back to the web browser we can see that nothing shows up until the page actually loads and then the state gets filled so we need to actually make this go homework button work as well so how do we do that because you know we can't really make use of the actual a tag because that's gonna result into a full page refresh so if you are guessing that we're gonna make use of react router then you are absolutely right so first of all we need to grab a named export from react router okay and that is going to be link and remember we did we did use this link right there in recipes as well and that is exactly what we're going to do inside of this recipe components as well okay so i'm just going to go ahead and break this button down into multiple lines cut this out and open up a link tag and paste it right there now the only thing that we need to provide here is the path name so remember we have two parts we have the home path and then we have the recipe path so currently in this inside of the society component we are indeed on the recipe path so right there all we need to do is we need to say that once this button has been clicked take us back to home page so for the home page the path is forward slash okay so now if we go back to the web browser and we can see that this has been converted to a link and if i press this we get taken to the home page and from there on we can search for another recipe so actually let's type something different because we have used chicken quite a bit okay shrimp and then let's just go to one of these the recipe and then yeah it's working just fine from there on we can go back to our homepage using this go home button okay so our application is pretty much done for the most part the only thing that's left now is you know when we go back to the home page our results are gone so we want uh you know we we want to keep our results you know when we go back to the homepage we don't really want to search through the you know the index again and grab everything we want to we want we want our results to be there just the way they were before we navigated away from this page so let's take care of that inside of our app.js file okay so i'm just going to close everything else because i don't think we need anything else anymore now inside of this app.js file we're gonna make use of a couple new react lifecycle hooks and those two are component did update and component did mount actually we've used component demand already so the only new one is componented update so component did update works something like this we don't really need these two arguments because these are for something a little more advanced but essentially the way this works is whatever happens inside of this method is going to happen as soon as the component has updated and when does the component usually update well when the state changes okay so as soon as the state updates the component is going to update as well so as soon as that happens what we're going to do is we're going to create a constant all right and we're going to call it recipes and then we're just going to make use of the local storage to store our data so what we're going to do is first of all we're gonna convert this into you know our our recipe state into the json format because local storage only takes strings it doesn't take any objects it doesn't take any arrays it doesn't take any numbers nothing it just takes string uh it just takes the string so as uh json basically is just a one big string so to convert this we're gonna say json dot stringify and then what what do we need to stringify well we need to stringify this recipe state so json.stringify and then this dot state dot recipes okay so once that's been done we need to actually assign it to local storage so to do that we can just say local storage and then you set an item in local storage you use the property called set item and it takes a couple of arguments the first one is the name of the item which is going to store this recipe array right there so we need to provide that into in a string so i'm just going to call it recipes and the second argument is the actual thing that you want to store and in this case we want to store our recipes our recipe state so this is what we're going to type in right there okay so now if we go back to our web browser open up the state and let's just search for chicken because right now it hasn't been updated but it's going to get updated as soon as you press search because that's when the state updates so now from there let's just look for local storage because i kind of forgot where it lives so performance application local storage and there we go we can see that everything that we looked for is inside of this recipes object so right there if we type in local storage dot get item and then what did we set the item to is recipes right so get item is an other method on local storage which we can use to grab the items that we set so in this case we set the recipes item right there so we can say localstorage.get item and then if you press it press enter we can see that we are getting everything in form of a string so you can see this is a quotation mark and it ends right there at the end and this is why it's a very ugly format because this is not json this is just a one big string all right so what's next well once we have actually set this to local storage now using another lifecycle hook called component did mount we're just going to oh that's not it now in this method we're just going to fetch everything that's inside of our local storage so to do that we first need to grab our stored item which in this case is recipe so i'm just going to create a new constant and i'm gonna call it json okay and i'm gonna set it to local storage dot and then in order to get an item we use the get item property and then we're gonna grab the recipes item that we just set okay so now we first need to convert it to the actual json format because currently it's in the string format because we can't display any strings or any of the type onto the web browser so it has to be in json okay so we can say we can create a new constant called recipes and then we can say json and then to pass a string we say json.parse and then we can type we can pass in this json constraint right there okay excellent so now all we need to do is we just need to set this recipes to this recipe state right there okay so this dot set state and then an object and then recipes and then this constant right there okay and now one neat bit of syntax in es6 is that if the name of the of the property and the key if these two names are the same then you can just make it something like this okay if it was something like recipe then we would actually have to type it this way but in es6 if the names of the keys and the values are the same then you can just do something like this okay now if you press save go back to the web browser we can see that we are indeed going through a full page refresh but nothing is changing we can see that we are still getting the results and let's just look for something else let's look for garlic press set and let's just do let's just view one of these recipes let's just view this one and we are indeed getting it back now if you go back to the home page we can see that we still have the recipe that we searched for okay well this is it for this video and i really hope you learned something from it thank you very much for watching and i will see you next time goodbye
Info
Channel: freeCodeCamp.org
Views: 61,195
Rating: undefined out of 5
Keywords: JavaScript, React, JS, Reactjs, React tutorial, WebDev, Web development React, React router, React v16, React 2018, HTML, CSS, APIs, API, JavaScript tutorial, React for beginners, React tutorial for beginners, react course, react api, api react
Id: tvfeBLMA_Q4
Channel Id: undefined
Length: 93min 11sec (5591 seconds)
Published: Thu Apr 25 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.