Build and Deploy a Google Maps Travel Companion Application | React.js

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello there and welcome to a project video where you'll build and deploy an advanced travel companion app using google maps with geolocation google maps api the ability to search for places fetching restaurants hotels and attractions based on location from specialized rapid apis data filtering and much more in this one video you'll learn advanced react best practices such as folder and file structure hooks and refs you're gonna also learn how to improve security by using environment variables you'll learn creating user interfaces using material ui you'll of course also learn working with google maps api and most importantly fetching data from unlimited sources using rapid api essentially you'll become the master of working with apis i initially planned on putting this as a paid course but i later decided to release it completely free for you guys here on youtube so to support this video leave a like comment and subscribe it shouldn't take more than a few seconds and i really appreciate it in the end of this video we'll deploy this application so that you can share it with your friends put it on your portfolio and get a job before we dive into the project i have an important announcement for you for quite some time now i have been working on something big i'm creating a custom platform where you'll be able to learn by creating even better and more professional projects it'll take a long time to turn this into a reality but i want you to make the most important decisions during the process so click the mailing list link down in the description so that you can stay up to date and choose which projects will be built first big news coming soon with that said let's dive straight into the video before we create a folder for our project code we must first visit rapid api the link is going to be down in the description the making of this entire app is possible only due to rapid api because we are using their travel advisor api this travel advisor api is just one of hundreds of thousands of apis available on their api hub you're gonna learn how to use most of these endpoints from this specific api how to get different hotels restaurants and attractions and finally we're gonna use one more api from their platform which is called open weather map this api is going to give us weather based on a city name or in our case based on the coordinates of the map so to be able to use these apis make sure to visit the rapid api link in the description and then you can click sign up or log in in this case i'm going to log in since i already have the account and you can log in with google github facebook or your regular email once you're in you'll be redirected to their api hub where you can find hundreds of thousands of apis this was the first step in our video now let's create our react application and then later on we're going to call these apis right from our react application before we dive into the code please allow me to give you a quick demo of the entire application at the top we have a navigation bar that says travel advisor explore new places and then in here we have entire google maps search so if you start typing something like new york you'll be able to see all the locations that are related to that search term we have beautiful images belonging to each single restaurant the restaurant's name rating number of reviews pricing all the specific certificates as well as the location and different types of food they prepare so everything is here in this nicely styled card as you can see this is how it looks like for example tomino is rated 5 stars out of 208 reviews the price is medium they are the 32nd best rated restaurant in new york city they have two certificates of excellence and they prepare spanish food on this location this is their phone number and if you click you'll be redirected to the tripadvisor page where you'll be able to read all the reviews also you can visit their website and as you can see this looks pretty good we can also filter restaurants by rating so let's search for all above 4.0 there we go and finally this website is not only for restaurants you can search for hotels take a look at this with just a bit of loading you get all the best hotels in new york city and the situation is the same you have a large image displaying the hotel you have the price ratings and all the certificates that they have and finally we also have attractions so let's say you're visiting new york this application gives you everything you need it gives you attractions you can visit places you can stay at and restaurants where you can eat at so in here you can see all the attractions that's looking pretty good and one more important thing is you can browse the map and locations reload every time you switch the map so there we go you can even unzoom to get more and you can click on a specific card and it's going to bring you right to it there we go soho you can visit everything there is to visit if you zoom out even more it's gonna give you more locations around new york and wider area i've also went ahead and implemented one more api to make this even more complete as you can see here we have the sun icon and right here we have the cloudy sun icon this is real time weather from new york we're gonna use one more extra api so that our visitor knows absolutely everything they need to know when they're visiting a specific place let's make sure our app works for different places so for example let's go to new delhi there we go it's currently cloudy there and take a look we have all the attractions there let's look for restaurants there we go so if you're visiting you know where to go since this is a big application during the process of building it you might come across a few errors that are going to happen to you and that's completely fine so if that happens the link to the entire github code is going to be down in the description make sure to visit it and then compare your code with the code right in here that should solve all of your potential problems while going through the video also while you're here make sure to give it a star as always to start off we're going to create a new folder let's name it something like travel underscore advisor there we go and finally we can also open an empty visual studio code window of course you can use any code editor in this case i'll be using visual studio code once you have it open simply drag and drop the folder right inside of it and we are in finally go to view and then terminal this is going to open the visual studio code integrated terminal now we're going to run some commands to initialize a react application to run these commands you have to have node installed so if you don't already make sure to visit nodejs.org and then simply download the current version once you do that you can simply run mpx create dash react dash app and then dot slash this is going to generate an empty react application right inside of your folder let's wait a minute while our application is initializing and we'll be right back and our application is initialized they say happy hacking we won't be hacking today but will be creating an amazing travel companion application with that said there's something that i always do to newly created react applications and that is to clean it up a bit as you can see we have quite a lot of files here which we're not going to use so let's simply delete the source folder and once it is deleted let's create a new folder called exactly the same now as you might know every react application needs to have an index.js file so this is going to be the first file we're going to create inside of the index.js file we can import react from react and then we can also import react react-dom from react-dom we're also going to import a file that doesn't exist yet that's going to be import app from dot slash app we're going to create that component really soon but for now let's say react dom dot render and then inside of that render we're gonna have the app component like this self closing component and then we're also gonna say document dot element and we're going to have root in every single react application we have to mount our application onto the root div if you're new to react let me show you where that div is we have quite a lot of files here as well so for now i'm going to delete them we don't need this favicon we also don't need these logos and the manifest so i'm going to delete all of them we only have the index.html and it might seem like we have a lot of stuff here but if we properly structure this out i'm going to put this in one line i'm going to remove these comments right here and you're going to notice that this is nothing more than an empty index.html document with a single div with an id of root and inside of here will be our entire react application with that said let's create our app.js this is going to be the starting point and the most important component of our entire application inside of here for now we're going to simply import react from react we're going to create a functional app component like this that's going to be const app is equal to an arrow function and then inside of there we can simply return in this case we're going to return a div inside of that div we're gonna have an h1 that says hello world and now that we have it of course it's not being used so we have to do export default app and finally if we end up seeing this on the screen that means that we have set up everything correctly before we go ahead and run this application let's open up view and then terminal and then inside of here let's install all the necessary dependencies throughout the process of building our application to install dependencies you can say npm install and then we can start listing them out the first dependency on the list is going to be add material dash ui forward slash core the second one is going to be add material dash ui forward slash icons the third one is going to be add material dash ui forward slash lab as you can see we'll use quite a lot of things from material ui then the next dependency is going to be add react dash google dash maps and then forward slash api we're also going to need axios and we're gonna need one more google map dependency this time for that little search bar at the top right so let's install google dash map dash react these are all the dependencies that we need so let's install them the process of installation is going to take a minute so feel free to grab a glass of water coffee beer whatever you prefer and get ready to code out this phenomenal project now that we've installed all the dependencies you can run npm start with that you can also close the terminal so that we can see our code better this automatically opened up our browser on localhost 3000 and we see hello world right here which means we've done everything correctly so far now is the time that we actually start building the layout and the functionality of our application let's start with the folder structure we're gonna have one new folder inside of the source folder which is going to be called components inside of that components we're gonna have four different components so let's create a new folder for each one of them the first one is going to be our header then also inside of the components we're gonna have a list this is going to be the list of places then we're going to have our map and finally we're going to have our place details component so let's call it place details now each one of these folders represents a component so let's create a component file for each one of them new file and that is going to be header.jsx let's repeat the process for all of them inside of the list list.jsx inside of the map that's going to be map.jsx and finally we are going to have place details so place details dot jsx each component is also going to have a separate style sheet coming from material ui so to create a style sheet simply create a new file inside of the folder let's start with the header and let's call it styles.js you can now copy this empty file three more times so list has to have styles map and finally the place details now let's create dummy components for each one of these components so we can start with a header and that's going to look like this import react from react const header that is going to be a functional component and then inside of there let's return in this case we want to return an h1 and the h1 is going to say header finally we also have to export that component so let's do export default header great so now this is our dummy component let's copy it let's first go to our list now to quickly rename a lot of things you can simply click on the header click f2 and then simply rename it in this case to list there we go and inside of there we can also say list let's go to our map copy and paste press f2 this is going to be a map inside of there we can also say map and finally to our place details we can paste it f2 this is going to be place details and then inside of there we can also one more time save place details now that we have all of the files and folders ready we can start importing them inside of our app.js so we can say import header from that's going to be dot slash components and then finally slash header and then just one more time header to get into that jsx component now we can duplicate this line two more times for the second time we can call this a list so to quickly rename it hold alt and then double click right there there and there this is going to be our list and then finally we also need a map so let's rename this to map great now we have everything that we need finally let's start importing some of the things from material ui to start creating our layout in this case we're going to say import curly braces we first need css baseline this is a component from material ui that simply normalizes the styles so it's just going to fix some paddings margins and background colors immediately for us and then we also need a grid that's going to be coming from add material ui forward slash core now inside of the jsx for our app we can turn this into a react fragment and then just below we can call a self-closing css baseline component instead of this h1 tag we're going to have our header component it's going to be a self-closing component below the header we're going to have our grid this grid is going to be of a type container so we can say container spacing is going to be equal to 3 and we can also give it an inline style that's going to be equal to width is equal to a string of a hundred percent remember since we're doing inline styles it has to be an object so you're going to have double curly braces inside of that grid we're going to have one more grid this grid is going to be of type item and it's going to have two properties xs is equal to 12. this means that this grid is going to take full width on mobile devices but then on medium devices and larger it's only going to take four spaces remember that list was only showing on the left side and the map was taking much more space this is what makes it happen only take 4 out of 12 spaces on medium or larger devices now we can expand that and we can copy that grid the first grid is going to contain our list component so we can say list and that list is going to be a self-closing tag finally the second grid is going to contain our map so let's say map which is also going to be our self-closing tag it said that the map is much larger when compared to the list so it's going to take eight spaces on medium or larger devices now let's save this and if our terminal is running we should be able to see this rendered on localhost 3000 and there we go initial layout and folder structure is done although this doesn't look like anything right now we simply have a header we have a list and then map on the side but we've done a lot of work we've prepared our code base for everything that's going to come right now so let's keep things going and let's create our header to start off we can close all of our other files and folders just so we have a clean workspace and then we can collapse it and simply open just the header.jsx inside of here we're first going to import a few things we can import in curly braces auto complete and this autocomplete is coming from react dash google dash maps and then forward slash api below that we want to import a few things from material ui so these are going to be app bar we also want to have a toolbar then we're going to have a typography an input base and finally a box all of this is coming from add material ui forward slash core so let's create the layout for our navigation bar instead of this h1 we're going to have the app bar like this and the position of the app bar is going to be static so we can say position is equal to static then inside of there we're going to have a toolbar that toolbar is going to have a class name equal to curly braces classes dot toolbar right now we're going to have an error saying that the classes is not defined but don't worry about that soon enough we're going to import the classes from material ui and we're going to add them inside of the toolbar we're going to have a typography that typography is going to be of a variant equal to h5 if you've never used material ui before don't worry i'm gonna lead you through the process but basically typography is simply every single text element but you can change the variant you can make it headings subtitles and titles in this case we want this pretty big so i'm going to leave it as h5 then we're also going to give it a class name equal to classes dot title inside of there we can simply say something like travel advisor below that we're gonna have a box in material ui a box is basically a div but you can simply set a display of flex and some other properties then inside of there we want to have one more typography so we can simply copy this one i copied it indented it properly and this one is going to be a variant of h6 and we're also going to leave the class name of title in this one we can simply say something like explore new places now still inside of this box but below this typography we're going to have our auto complete component it is not going to be a self-closing component so that means that we want to have something inside of it more specifically we want to have one div and that div is going to have a class name equal to classes dot search this is going to be our search bar or search box inside of that div we want to have yet another div and this div is going to have a class name equal to classes dot search icon inside of that div we can of course have our search icon so let's call it like this search icon and it is a self-closing tag of course we have to import that search icon so at the top let's do just that import search icon and this will be coming from add material ui forward slash icons not core in this case it's going to be icons finally below this inner div we want to have one more thing and that final thing is going to be called input base it is going to be a self-closing component with a few props first it's going to have a placeholder equal to search dot dot and then we're going to have some classes in this case classes is going to be equal to an object because we want to add multiple classes first we're going to set our root class to be equal to classes dot input root and then our input is going to be set to classes dot input input like this it's a bit weird of a naming but it should do us just fine great we're done with the layout but if we try to render this right now that wouldn't work because we have a lot of errors first of all our classes are not defined and it also looks like we're missing something right here at the top it says that we have to add one more forward slash and then search here is where icon is great so now we can clearly see that we are missing all of our classes so how do the classes work in material ui well remember we already have the styles.js file so inside of there we need to import some things in this case it's going to be import make styles and this will be coming from add material ui forward slash core forward slash styles below we want to export these styles so we can say export default make styles we can call this as a function and then inside of there it requires one more callback function the callback function inside returns an object so we have to wrap it in parentheses like this great finally whatever styles you want to add you can simply add them in css in js type of way that means that if you want to have a class name title you would create a title property that's going to be an object and then you can set the color to be equal to red it is kind of clumsy to write css in this way but i found it to work really really well with material ui and you get a lot of benefits this way because they also give you a theme object which allows you to use their colors paddings and everything else now this is not a css video you're here to create this phenomenal project to learn how to create logic use apis google maps and everything else that's why i don't want to waste your time by writing this css by hand so find the link in the description and there you'll be able to find all the styles for this specific project once you have them simply copy and paste them in each specific style sheet header styles have the most css but you can see it's not that a lot but then all the other component styles don't have a lot of css at all so you can simply inspect it see if you want to change something and really learn it if that's what you want with that said now we have the style sheet and finally we can go back inside of our header and we can import it so right inside of here we can say import use styles and that's going to be coming from dot slash styles great now just by looking at the name you can notice that the use tiles seems to be a hook so let's call it how we usually call hooks const classes is equal to use styles and then we call it as a function okay now that we're done with the layout and we have our styles we can simply save this and take a look in the browser but before we do that let's for now simply disable the autocomplete by commenting it out right now we don't have everything set up for it yet so if we simply save it and run it with it we're gonna get some errors but don't worry we're gonna re-add it back really soon now let's take a look in the browser as you can see this already looks much better we have our heading travel advisor and on the right side we have explore new places with this nice search bar that has a search icon now we are ready to start creating the main parts of this application which are the list and the map let's go ahead and do that right away map is of course the main part of our application so let's start with that i'm going to open up our map component and then in here we can start implementing the jsx let's first import a few things we're going to import google map react this will be coming from google dash map dash react then we're gonna import some things from material ui so we can say import we're gonna need a paper paper is basically a div with a background color we can also use typography and finally use media query use media query is going to help us with making our map more mobile responsive we are also going to need a location outlined icon so let's say import location outlined icon and this will be coming from add material ui forward slash icons and then forward slash location outlined without the icon at the end and finally we're also going to import a rating component so import rating from add material ui for slash lab some of the material ui components are still being worked on rating is one of them that's why we're not importing it from core we are importing it from forward slash lab okay and we're going to repeat the process for importing the classes as well so we can say import use styles from dot slash styles and then again you can visit the link in the description and you can simply copy and paste the styles right in here once you have the styles we can go back and we can start implementing the layout at the top we're going to call our hook which is going to be cons classes is equal to use styles and we call it as a hook then we're also going to call the use media query hook so if we can use it later on we can say const is mobile is equal to use media query and we pass in a string that string is going to have parentheses and then inside of there we can say min width is equal to 600 pixels this means that this is mobile variable is going to be set to false if the width of the device is larger than 600 pixels now that we have everything we need let's start writing our jsx we're first going to have a div that div is going to have a class name equal to classes dot map container right inside of that div we're gonna have possibly the most important component out here and that is the google map react google map react is not going to be a self-closing component so we can open it like this but we're gonna have quite a few props we want to pass to it first property is going to be bootstrap url keys and then inside of that object you can say key is equal to and now in here we can specify the google maps key to get our key we'll have to create a new project on google developers console we're going to do that as soon as we add all the other props required for this google map react the second property is going to be default center so this is going to be the center of our map and then in here we can pass the coordinates right now we don't have real coordinates so i'm going to create const coordinates is equal to that's going to be an object that's going to have the lat property and it's also going to have the lng property this is the latitude and this is the longitude and in there we're going to pass the chords below our default center we're going to have a real center so this is the current center of the map and in there we can also pass the coordinates of course this here should have been coordinates then we can also set up the default zoom default zoom in this case i found 14 to be working the best so let's leave that finally we're gonna have some margins so let me say margin is equal to and then it accepts an array it has four different properties we're going to say 50 to the top 50 on the right 50 on the bottom and 50 to the left side later on we're gonna have three more properties which we're gonna left empty for now one of these is options then we're gonna have the onchange property which is gonna be really important when you change the map and finally we are going to have the on child click property which is going to be used when you actually click on a restaurant on the map right now for this to work these must not be empty so i'm just going to put an empty string in there and this is it these are all the props that we need for our google map react now is a great time to get that key to get the api key you can go to console.cloud and then forward slash project create if you visit this link you'll be redirected to the google cloud platform and there you'll be able to create the project and get the api key of course if you're not logged in you'll have to log in first but then you should be redirected to this page now i'm going to make this a bit bigger for you and we're going to give this project a name let's call it travel advisor okay great and finally i'm gonna click create okay at the top left you should be able to select your project and you can click travel advisor to switch to it it should take just a few moments to create it then on the left side you should be able to see apis and services and you can click dashboard in here you can start searching for maps there we go maps javascript api is the one we'll be using so you can click enable it took just a second and it redirected me to this page finally you can click on maps javascript api and once you're here go to credentials on the left side once the page loads click create credentials in this case we want to create an api key and there we go our api key is right here let's copy it and in our code right here where string of key is let's paste that api key later on in the video we're going to convert all of the api keys and data that should be secure to environment variables that way we're the only ones who can access it with that said just before we save i notice there's one small error right here and that is that i miss type styles that's a rookie mistake and at the top location outline icon is supposed to be location on outlined icon same thing here at the end location on outline save this and let's take a look in the browser and there we go this app already looks like something we have the map on the right side we can even make it full screen and let's zoom out a bit looks like we're in the middle of the ocean the entire map loaded now if we zoom out that's great we have a few different routes we can go right now we can start implementing the search right now of course if we search for something like new york right now it's just a basic field but we want the functionality to fetch all of the cities streets and everything in the world we can do that or we can immediately start creating the list or we can start fetching the restaurants this is the moment where you can really choose what you want to do next in this case i think that creating the layout for the list makes sense that way most of our layout is going to be done and then we'll be able to get dirty and start working on the functionality of fetching all the restaurants hotels and attractions you already know the drill starting with the list is not going to be hard we're just going to open up our list component we're going to import a few things and then we'll be able to start creating the layout so what are we going to need from material ui in this case we can say import we're going to need a circular progress that is material ui's loading bar then we're going to have a grid a typography one input label as well as the menu item and finally a form control and a select element all of this is of course coming from add material ui for slash core in this case let's also import our styles so we can say import use styles from dot slash styles as simple as that you already know the procedure i think you even have all of the styles open in the browser right now so simply copy and paste the styles for our list there aren't many as you can see right there just some simple heights margins paddings and so on nothing you wouldn't be able to do yourself so don't worry about that now that we have the styles we of course have to do const classes is equal to use styles and with that we are ready to start using all of these components so first we're going to have a div component that div is going to have a class name equal to classes dot container below that we're going to have a typography component and that typography is going to have a variant equal to h4 inside of the typography we're going to have something like restaurants hotels and attractions around you below the typography we're going to have a form control element so let's create that form control form control is going to have a class name equal to classes dot form control inside of our form control let's create our input label our input label is simply going to say type and just below our input label we of course have to have the corresponding select element our select needs a value which we're going to leave empty for now and it also needs an unchanged property that on change is also going to be empty for now inside of that select we're going to have a menu item like this menu item and that menu item is going to have a value equal to restaurants and of course it's simply going to say the same thing restaurants so if we select this first menu item we'll get to restaurants now we can duplicate that two more times if we select the second one that's going to be hotels like this and the third one is going to be attractions and finally attractions now this data has to be modified using state so let's import use state in curly braces from react so let's create a use state hook const and then we're going to have brackets and then inside of there we can say type and set type the first thing is our state and the second thing is a function that modifies that state that is going to be equal to use state as a function and it accepts one parameter which is the first initial value that's going to be put into the variable of type so in this case let's say that the restaurants is the default value now that we have our type we can say value is equal to type right inside of this select and on change what do we want to do well on change is going to give us a callback function that has the event as the parameter and we can simply say set type is equal to event.target.value inside of the event that targeted value is where the value of the clicked element will be so if you click on hotels this thing is going to be populated with hotels and then that's going to set the variable of type we also want to copy this whole thing one more time the entire form control this part is going to stay the same the input label is simply going to say rating instead of type this time and then we have to also copy the use state one more time this time we're gonna have the rating and we're gonna have the set rating at the start our rating can be set to just an empty string so now that we have the rating instead of the value of type we're gonna have rating and instead of the set type we're gonna have the set rating at the start we're gonna have old ratings so restaurants or hotels with old ratings so we can say the value is equal to zero then just below that we're gonna have three stars so we can say above 3.0 then we're going to repeat that this one can be 4 and we're going to say above 4.0 and finally we can have a number of 4.5 and we can say above 4.5 so these are really good places great we've written a lot of code now let's look at it in the browser as you can see we now have this great heading restaurants hotels and attractions around you we can choose between restaurants hotel and attractions and we can choose the rating from all to above 3.0 4.0 and finally above 4.5 that part is ready but now is the most important part we have to start rendering through the list of restaurants and then displaying a card for each specific place so far we haven't yet fetched restaurants hotels or attractions so let's create a variable const places which is going to be a dummy variable for now in there we can simply say cons places and let's say that each place is an object and it's going to have a name property so the first one is going to have a name of something like cool place let's paste this out properly and let's create one more object the second one is going to be let's say pub and let's say best beer and finally the third one is going to be best steak let's say these are the names for our places now that we have our places just below the form control we can actually loop over them so i'm going to create a grid that grid is going to be of a type container it's going to have spacing equal to 3 and it's going to have a class name equal to classes dot list inside of there we can open a block of code and we can say places question mark dot this means only if you have places only then map over them map of course takes in a callback function like this and then in each iteration of the callback it has one new place so if we're mapping our places we can say in here place we're also going to need the index and index is always given to you as the second parameter to the map function now we need curly braces if you really want to open this as a function but in this case we only need parentheses because we're going to instantly return a piece of jsx so for each place we want to return a grid but this time not a grid container rather grid item that grid item is going to have a key equal to index this is usually not a good practice especially when you're deleting items from the list but in this case we won't be deleting them so it's fine and finally we want to say xs is equal to 12. that means from extra small devices all the way to the big devices they're gonna take the full width of the list container which is 12 spaces and finally inside of the grid is where our card should be our card is yet another component that is a custom component we need to create and that is the place details so let's import at the top the place details component let's do it like this import place details from dot dot slash place details forward slash place details to get to the component now if you scroll down instead of the card we can render the place details which is going to be a self-closing tag of course one thing we have to pass into it is going to be a place which is equal to this place right here great let's scroll a bit up and i'm just going to duplicate this two times just so we have more places to see now that this is saved let's visit our place details and remember as props we're getting our place so this is how you can get props really easily we passed it right inside of here and we're getting it right inside of here instead of place details let's render place dot name remember each place has a name so let's render it for each one once you save this let's take a look in the browser and there we go alongside the header and the select fields now we have the list at this point this list is looking kinda boring it's just headings with the names of different places like cool place best beer and best steak but that's more than we need for now our next step is to finally fetch the data for all the restaurants hotels and attractions and that way we'll have something to render out here and also to render on the map now we're finally getting our hands dirty and i think this is the part of the video where you'll be able to learn the most we'll work with the apis i'll teach you how to fetch data how to properly structure that data and how to keep it clean it's always important to keep your code clean and secure so we're gonna do that right away to fetch our data we of course have to make api calls and to keep our code tidy we're going to create a new folder inside of the source folder which is going to be called api right inside of there we can create a new file called index.js this is where we're going to keep all of our api calls inside of that file we're going to import axios from axios axios is the library that's going to help us make our calls and in here let's create a function that's going to make that api call we can say const get places data that is going to be an async function so we can say async and inside of there we are going to have a try and catch block inside of the try block we usually have a request and if that request is successful then the code runs as it's supposed to run inside of the try but if the request fails then our code is redirected to the catch error block with that said let's start by creating our first request we can say const response is equal to and then a wait and then in here we're going to make the axios dot get call now of course the main question is to which url are we going to make our api call to and that is where the rapid api comes into play you can search for travel advisor and then click on the first api that appears you'll be redirected to this page and then right here if you're using it for the first time you have to click subscribe to this api that's going to bring you to the pricing section and then choose the basic plan as you can see it is completely free up to 500 requests a month for our testing purposes that's going to be more than enough once you're done with that you can go back to our endpoints and then in here we can see what endpoints can we make we can make endpoints to locations to get the autocomplete we can also post different hotels or get hotels we can list them by latitude and longitude or we can list them by boundary there are also some more endpoints which are deprecating we also have the same thing for restaurants and for attractions so what do you say that we first make this work with restaurants there is the restaurants list by latitude and longitude api call as you can see we have the latitude and longitude and you might think this is great because we already have the coordinates that are in the center of the map and let's click test to check it out and we got back 33 restaurants based around that central location that is great but if you think about our application if we wanted to showcase everything in the center of one dot for example let's say that we go to united states and let's say that we are in kentucky if we make this a central point and if there are a lot of restaurants all of the restaurants are going to be populated in this exact point but we don't want to see the restaurants just around this central point we want to see it in our entire visible area of the map that's why we're going to use list in boundary in this case you have to pass the latitude and longitude of the bottom left corner of the map and also the top right corner latitude and longitude so we have to find the position of the bottom left corner and the position of the top right corner if we do that the restaurants that we fetch are going to be scattered across our entire map so how exactly can we make this call so that we get back this data well rapid api makes it extremely easy as you can see you can select your language right there javascript axios and you can basically just copy everything that is in here let's do just that once you copied it we're going to paste it right in here at the top and then we're going to make some small adjustments in this case i'm going to take this url and i'm going to store it in a variable we can say const url is equal to to this specific string since we're using axios the method is automatically going to be set to get so we don't have to use that now when it comes to params we definitely need the bottom left latitude and longitude and the top right latitude and longitude but we don't need any other of these options so i'm simply going to delete them for now and then we also need the headers this is where your rapid api key resides that means that we'll also have to exchange this to environment variables later on in the video this part we can delete because we already have our axios call right there so what we can do is we can use this url right here axios.geturl and then the second parameter to the url are the options so you can simply pass the options object right inside of here for now this is going to be all that we need we could return the response but we're not really interested in the response itself we're more interested in what's inside of the response and that is going to be data so we can immediately destructure the data right in here and then one more time we need to destructure the data from inside to get to our restaurants finally we can return that data right here also in the cache we're simply going to console.log the error now that we have our function we can export it by saying export const get places data the main question now is where are we going to call this function and the answer is inside of the app.js so let's go right there and then at the top let's import get places data and this is going to be imported from that is going to be dot slash api great so now the question is how can we call this function inside of our functional app component the answer is we are going to create a use effect so just at the top let's set up our use effect we have it imported and let's set it up right inside of here by saying use effect that is of course a function that accepts another callback function and don't forget at the end of the function we have to have the dependency array if you leave this dependency array empty that means that the code inside of this function block will happen only at the start of the application and right now that's exactly what we want to do so i'm going to say get places data and we're simply going to call it as a function now don't forget this function returns something more specifically it returns the restaurant's data so let's set the data to the state i'm going to create a new use state field i'm going to import use state from react as well and then we're going to create a new use state field our field is going to be called places and the setter function is going to be set places of course this is going to be equal to use state and at the start our places can simply be an empty array now that we have that you also have to remember that our get places data is an asynchronous function that means that we have to call the dot then on it i'm going to put the dot then right here and the dot then accepts a callback function which then has the data so right here we're getting that data and what do we want to do we simply want to call the set places and set the data to those places one good thing we can also do would be to cons a log data just so we can see if it's being fetched properly great this seems alright we have the function making a request of course everything is static right now we don't have real coordinates here but we're going to make this work really really soon we just first have to see if it's going to work with static coordinates if we go back to our browser we can right click click inspect and then open up our console and there we go we have seven different locations all of these are restaurants every restaurant has a lot of information like an address address object with the entire city street and country it has different awards categories different types of cuisines and a lot of different information that we can use to display on the map and on our cards that means that we are fetching the data from the api correctly this was extremely easy right rapid api makes it so easy to make api requests but now is the time that we make this dynamic we have to get real information from the position of our map and then based on that we have to call only the right restaurants for that map to do that we'll have to pass some information into this get places data function so let's create more use state fields more specifically i'm going to set a variable of coordinates and also set coordinates that is going to be equal to use state and then at the start we can leave that as an empty object we also need one more thing which is going to be cons the bounds and also set bounds remember the top right and the bottom left corner i was talking about we are going to call them bounds and we can say equal to use state and the bounds are the start going to be set to null now we have this data but it's not populated yet these are just empty values so we have to pass our setter function as props to our map we're going to pass the set coordinates prop which is going to be equal to that setter function of set coordinates and i'm going to repeat the process one more time for the set bounds also our map is going to have to use these coordinates so let's also pass the state itself coordinates is equal to coordinates now if we go to our map our map is going to be receiving different props more specifically set coordinates set bounds and also the coordinates themselves as you can see before we even declared empty coordinates but we're no longer going to need that so i'm simply going to delete it now the question is how are we going to know when the coordinates or bounds of the map change and the answer is google map react will be doing that for us we simply have to call a specific on change function inside of the onchange we are of course getting a callback function that has the event inside of it so right inside of there we can call these set coordinates and then inside of there we are going to set it to an object an object that has the latitude property which is going to be equal to e dot center dot lab and also we need the lng property which is going to be equal to e dot center dot lng but you might be wondering how do i know that this event has the center lat and everything else we're going to use well an easy answer is always console log everything that you can so i'm going to console log this event and let's check it out in the browser as you can see we are cons logging it it has the bounce property it has the center property and also the margin balance in this case we'll only need the center and the bounds for the center you can see it's lat 0 and lng 0 but then again for the bounds we're also going to use the north east and the southwest these bounds are going to be really helpful with setting our top right and bottom left corners so to do that i'm going to delete this kansa log and i'm going to call the set bounds our set bounds is also going to be an object and it's going to have the northeast bound which is going to be equal to e dot margin bounds dot northeast we're also going to have the southwest which is going to be equal to e dot marginbounds that southwest this is all that we have to do to successfully populate these variables so now if we go back inside of our app and if we console log these variables right there coordinates and the bounds what do you think the values are going to be are they actually going to change when we change the map think about it i'm going to save it and let's test it out before we check it out let's properly set these coordinates here at the start we can say the latitude is going to be zero and the longitude is also going to be zero well if we reload and open up the console you'll see there are a lot of warnings errors and stuff like that but to just get a clear view click here show console sidebar and just click info that way you'll get more meaningful messages so as you can see latitude is zero longitude is zero that is the starting value and the bounds are null just as we said it at the start but now if we move over if we switch it nothing is going to happen the values are not being updated why do you think that is the case well if we go back to the code even our editor is letting us know react hook use effect has missing dependencies bounds and coordinates if we want this code to be reran every time that the map changes we have to add the coordinates right there and also the bounds that is one problem solved but i also want to do something more i want to automatically set the coordinates to be the coordinates of the user's location so as soon as the user launches the page we should be able to get their latitude and longitude we can do that by using one more use effect this used effect is only going to happen at the start remember use effect is a callback function and then we have the dependency array now we need what we had before an empty dependency array because this should only happen at the start to get the user coordinates we can use the built-in browser geolocation api we can say navigator dot geolocation dot get current position and then in there we're gonna have a callback function we can choose what do we want to do with that data so let's space it out like this and in here we are of course getting some data but we can destructure it to immediately get the coordinates and then we can immediately destructure it one more time to immediately get the latitude and the longitude now that we're getting the data we can say set coordinates is going to be equal to remember that's going to be an object it's going to have the lat equal to latitude and the lng equal to longitude and finally now that we're getting the coordinates we no longer have to set these default values right there we can simply leave this as an empty object now our browser should be getting our geolocation immediately and our map should be positioning around our location let's save it and check it out if you reload the page you should immediately see latitude and longitude in this case i've used a mock location i'm not really in berlin right now but google chrome allows you to mess with the geolocation if you click these three dots right there click more tools and click sensors you'll get this little page right there and there you can override your current location for example i can set london as the current location reload the page and it will get me there in this case i'll stay with berlin reload one more time and remember you should be seeing your own location of course if you have the location allowed at the top great now we are ready to actually fetch real restaurants around our location and that's going to be the easy part now trust me we already have the coordinates and the bounds bounds are more important in this case we simply need to pass them over to our get places data so as the first parameter we can pass the bounce dot southwest sw and then also bounce dot north east great now we are passing that over to the function we can go back to our api and now we can accept those bounds right there we can say sw and northeast so how can we actually pass these values to our api request well as you can see here there are static values so i'm going to copy this entire object remove it from here and then simply paste it right here as the second parameter of our api call now we can remove all of these values which are not true they're just static and we can simply use our southwest and northeast properties to get the real bounds so we can say southwest that lat that is going to be for the bottom left latitude then also for the bottom left longitude we're going to use the southwest.lng and finally for this we have to use the north east latitude and northeast longitude so let me repeat one more time just so we don't have any mistakes bottom left is going to be southwest and then the top right is going to be the north east great and we are also passing the headers now the data that's being returned should be inside of our map let's check it out in the browser as you can see i got 33 restaurants in this case and this address seems to be correct as you can see berlin germany and if i keep scrolling a bit more down you'll also notice berlin germany so we are indeed fetching correct restaurants and now we can start displaying them either on the map or we can start with the list considering we already started with a list let's go ahead and implement that nice looking card and we'll be able to see restaurants in no time so one question is how can we get these places which are in the state inside of the app.js which you can see right there to our list and the answer is pretty simple we are simply going to pass them over places is equal to places now if we open up our list go there you'll notice that we've been using these fake places we no longer have to do that i'm going to delete them and simply at the top i'm going to destructure the places from the props now if we save that we can go back and already we have the names for all of these places but these restaurants have so much more information so let's render a nice looking card for each one of them we can do that by scrolling down seeing that each restaurant is a place detail and we're passing all the place information so let's go into our place detail component i'm going to close all of the other files and we can simply focus on this one at the moment so first of all it would make sense to console log the place just so we know what information do we have as you can see we've already seen this we have the address address object awards booking cuisine there is quite a lot of information so feel free to go through all of this and make the card look even better include more information if you want to you can include the distance the establishment type and everything else you'd want but in this case we're gonna make a decent looking card so let's import some things from material ui we can say import and we're gonna need quite a few things we're gonna need a box of course the typography for text we're gonna have some buttons here a card card media for the image card content card actions that's where our buttons are going to be and finally a chip all of this is coming from add material ui for slash core we're also going to have some icons so we can say import and that's going to be location on icon from add material ui forward slash icons forward slash location on without the icon at the end and then we can copy that part we're gonna need one more icon this one is going to be phone icon and it's going to be coming from just phone finally we're also going to import that rating component which we imported in the map but haven't used yet so import rating from add material ui forward slash lab and then forward slash rating this is going to be it for the external imports we just need to import the styles so we can say import use styles from dot slash styles of course that's coming from styles.js inside of the place details and these are going to be incredibly simple we have some styles for the chip the subtitle and just some spacing so nothing special right here let's go back to our component and now we can start implementing the layout of course first we can get the classes by saying cons classes is equal to use styles like so and we can wrap everything inside of a card component our card is going to have the elevation equal to six that's going to give it a nice shadow effect inside of the card we're gonna have our card media card media is a self-closing tag with a few properties the first one is going to be style in here we need to define the height of the image in this case let's go with something like 350. of course feel free to modify that if you want to then we're also gonna use the actual image the image we have to use a ternary expression to check if the restaurant actually has the image not all of them do so we can say if there is a place dot photo in that case we can use the place dot photo dot images dot large dot url this is going to be where the url of the image will be stored at and finally if we don't have an image we can use a demo image of a restaurant that i found online you'll find this link somewhere where all the other styles are great and finally we need a title for our image in this case the title can simply be place dot name and that's going to be it for our card media below that we are going to have a card content everything else is going to go inside of the card content first of all of course we have the name so we can say typography this typography is going to have a property of gutter bottom that means that we're just going to give it some extra margin at the bottom and the variant is going to be quite big it's going to be heading 5. inside of there we simply want to render the dynamic value of place dot name let's save it and let's already see how it looks like this is already so much better you can see all the restaurants in berlin for somebody this application will already be great but you know that here on javascript mastery we always go a step further so i want to really make this pop we're going to add so much more information here if you appreciate that definitely make sure to leave a like comment and subscribe let me know that you're in this current part of the video besides that you might have noticed that we've seen one image a few times and that image is let me show you this one this is the demo image we used if there is no restaurant you'll be able to see it a few more times like right here considering that we're gonna write a lot of jsx code here it might be better if we put our browser side by side with the editor that way we'll be able to see the changes live as we make them okay i simply drag and drop my editor to the side and now we are ready to continue writing code still inside of our card content but below the typography we're gonna have a box component this box is going to have a display equal to flex and it's also going to have justify content equal to space between we want to do that because we're going to have two typographies inside of there the first typography is going to have the variant equal to subtitle one and we're simply going to say price inside of there now the second one we're going to copy it the second one is going to have a gutter bottom like this it's also going to be variant of subtitle 1 and then inside of there we can render place dot price underscore level this is going to give us the level of the price for this specific restaurant and as soon as we save it you can see price and you can see this one is a bit this one is cheap but if we go here this one is a bit more expensive now we can copy this exact part and we're gonna use it for the ranking so right here instead of the price i'm gonna say ranking and instead of the price level we're simply going to use ranking let's save it and as you can see ranking 14 out of 6 000 restaurants in berlin nice now we're going to do something just a bit more complex we want to map over all of the awards that a restaurant has gathered we can do that by opening a dynamic block and saying place question mark dot we use this to be sure that the place exists then we can access the awards and then one more time question mark dot and finally we can map over it of course map accepts a callback function and in there we're not going to have curly braces we're simply going to have parentheses because we want to instantly return something inside of the map we get a singular value of what we're mapping through so in this case we're getting an award for each award we want to show a box like this that box is going to have a display of flex and also justify content of space between it's also going to have align items equal to center inside of there we can render a small image like this img it is a self-closing tag that has the source property and we're going to say award dot images dot small of course every image has to have the alt tag so we can simply say award dot display underscore name great let's save it and as you can see here we have those little award icons one thing we can do is to this box we can say m y is equal to one m stands for margin and y stands for y axis top and bottom so this is going to give it a margin of top and bottom one as you can see it's going to space them out properly this is a material ui feature and finally still inside of the box but below our image we want to have a typography explaining that specific award so that can be a subtitle two variant is equal to subtitle two and the color is going to be equal to text secondary so it's a grayish color and then inside of there we can display award dot display underscore name let's save it and check it out take a look this restaurant got three certificates of excellence 2019 2020 and 2021 that's great finally we also might want to know which type of food does each restaurant prepare let's open a new dynamic block and say place question mark dot cuisine and then dot map inside of there we have a callback function and as with every map function we get a type of the cuisine right there but we're only going to use the name of the food so we can simply say name we destructured it right there so for each one we want to show a chip component if you're not sure what a chip is you're going to see it really soon it's a really straightforward component the only thing you have to do is pass in the key because we're mapping over it then you have to give it a size in this case i'm gonna set it to small it has to have the label in our case that's going to be the name and finally we're also going to give it one class name class name is going to be equal to classes dot chip and if we save that take a look looks like i've missed one question mark and i've got cannot read property map of undefined so this question mark dot is a new feature in javascript and as you can see it can save your day quite a lot of times so one of the many restaurant didn't have a cuisine property and therefore we weren't able to map over it so as soon as i add that question mark the issue is going to be fixed so you always have to know that you absolutely have something before you try mapping over it looks like we also have one issue inside of our app right here we're trying to send the bounce that southwest and north east this worked before because our bounds were already filled but now as we don't have them it's not possible to call the dot southwest of null so inside of here line 13 make sure to change this to an empty object as well now if you reload we're back to having all the restaurants right here and look at that we can also see the chips so each one of these little gray pills is called a chip in material ui language okay with that fixed we are ready to add final details to our place details we have to know the address of the restaurant so we can say if place question mark that address if it exists in that case we want to render a jsx block that's going to show the address that is going to be a typography component that typography is going to have a gutter button property and also the variant is going to be equal to body 2. color is going to be equal to text secondary and finally it's going to have a class name so we can say here class name is equal to classes dot subtitle great finally what are we going to put inside of there well we're going to use our location on icon it is a self-closing tag and then right next to it we're going to render the place dot address let's save it and as you can see our location pin is right there and here is our address now that i look at it this here should have been the subtitle 2 it would look just a bit better finally we also want to know the phone number so i'm going to copy this whole part and we're going to just make a few changes if we have the phone then we're going to render something this is going to stay a subtitle the class name is going to change to classes dot spacing and we want to render the phone icon of course next to the phone icon we can render place dot phone let's save it and as you can see now we have the phone as well and the final part is adding the two buttons that can lead us to the trip advisor page of a restaurant and to the restaurant's own website so let's create a card actions part inside of the card actions we can have a button this button is going to be of a size is equal to small it is going to have a primary color so caller equal primary and it's going to have the on click property let me move this a bit to the right for you on click we want to create a callback function and then simply call the window dot open and then in here we have to use the url we want to open and that is going to be place dot web underscore url the window.open also accepts a second parameter which is a string that says underscore blank if we add this it's going to open that website in a new tab opposed to just replacing our own website okay and finally inside of there we can say trip advisor now we can also copy this button and everything is going to stay the same we're just going to change the url from web.url to website and again change the text to website with this i'm going to indent this properly remove these spaces save it and this is our card fully done as you can see we have these two buttons i'm going to click to the tripadvisor page of the first one okay this seems like a great restaurant it's well rated you can read the reviews and then decide if you want to go there or if you're still not convinced you can click website they also have a good looking responsive website so we're surely gonna go there right and we're done with the cards let me maximize this and i'm going to put this to the side as you can see this is already looking so much better now each restaurant has so much more information about it the next thing we can do is to take the data about these restaurants and display them on the map so let's do that right away our next really important part is taking these places from the app and then displaying them on the map we can do that by going to app.js taking the same places we've been passing over to our list and then sending them over to our map as well so we can say places is equal to places as you can see we're sending a lot of props from one component to another this is still okay because we're only sending it one level deep from our app to our map but we're not sending it two or three levels deep whenever that happens for you i would advise you to switch to using either redux or more simply react context with that said we're passing the places so now inside of our map we can finally destructure them from the props right here and you might be wondering how do we actually show the pins on the map well google map react makes it incredibly simple you simply have to render them right here inside of the map so let's open a new dynamic block and say places question mark dot and in this case we want to map over them again we're looping over it so it's the same situation and we're getting a singular place right here for each place we want to render a div and this div has to have a few properties we're going to give it a class name in this case it's going to be classes dot marker container and then most importantly we have to have the latitude which is going to be equal to place that latitude and also we have to have the longitude which is the lng which is going to be place dot longitude we're getting these values as strings and in here they have to be numbers so we can use the number constructor to convert these values into numbers so make sure to write it like this and now since we're mapping over this div we have to have the key in this case we can set it as i which is the index from inside of our map now inside of our div we want to render different things depending on if we're on mobile device or on desktop we can say if we are on mobile device so if is mobile in that case we simply want to render out the icon so we can say location on outlined icon let's see if that's how we called it at the top location on outline icon and let's pass the caller which is equal to primary and also the font size is equal to a string of large great but if we're not on mobile we want to render just a bit more information so in this case we're going to have a paper component paper is basically a div with a background and it's going to have elevation equal to 3 that's going to give it some box shadow we're also going to give it a class name equal to classes dot paper inside of that paper we're going to put a typography this typography is going to have a class name which is going to be equal to classes dot typography it is also going to have a variant equal to subtitle 2 and it's going to have gutter bottom because we want to have some margin at the bottom and in here we simply want to render place dot name finally we need just two more things one is going to be the image our image is going to have a class name equal to classes dot pointer and then we also want to have the source we can copy the source from our place details at the top because it's going to be the same so let's copy this entire thing right here okay and i'm going to say source is equal to and i'll paste the entire ternary from our place details great finally we also need the alt tag and the alt is going to be place dot name and the last thing is going to be the rating let's save it and see how does it look like okay as you can see right now we have just the pins even though we are on desktop based on what we've seen that means that this is mobile variable is actually the is desktop and that is mobile so if the min width is larger than 600 that means that it is desktop so we can say if it's not desktop then show the pin otherwise show the paper and all of our restaurants are here as you can see we can hover over them to see them entirely and right now we cannot yet click on them to see more details on the left side but they are definitely here let's just add the ratings below the image to add the rating we'll use that experimental rating component it is a self-closing tag and we're going to give it a property size which is equal to small we're also going to give it a value which is going to be equal to a number we need to use that number constructor to get the rating and then we're going to pass the place dot rating inside of it and finally we need to pass the read only property because our users cannot change the ratings we're only reading it now that i think about it i think that we forgot placing the rating on our list so let's copy it and let's go back to our place details our rating should have been just below this typography to display our rating i'm going to copy this box right there and just change a few things instead of this typography we're going to paste the same rating we've used before but it's not going to be small this time and then our bottom typography is going to say out off and then in here place dot num underscore reviews and then finally reviews let's save it see if it's imported correctly yep in here we have the lab forward slash rating and let's see if it's imported correctly in the map in here we have just form slash lab but we need lab forward slash rating so let's add that right here with that said we should be seeing all of our paper restaurants on the map and now on the left side we should also see the rating in our list there we go we have 5 stars out of 143 reviews and now we can see all of the ratings right inside of our map with the image and with the title of the restaurant this wasn't that hard right once we got all of the data from the rapid api we just simply had to display it on the left side and on the map the key thing here was knowing that we have to use the latitude and the longitude to display those places right inside of the map now that we're displaying these places on the map let's make them clickable and that's exactly where this on child click method is going to come in handy on child click is an event listener so we're going to have a method that's going to listen for our events and whenever we click on a child we are going to get it right here as a parameter and then what do we want to do with it well we somehow have to get the information about which child was click from the map component all the way to our list component and how can we do that well we could create a child and set child click field right here a state for example and only use it inside of the map not inside of the app or place details or the list so in this case we're going to use a method called lifting the state up so let's say that we start by declaring the state field right here we're going to use the use state we're going to call it something like child clicked and also set child click and initially it's going to be set to null but now we want to take that state to the parent component of both the list and the map and in this case that's going to be the app component so right inside of here we are going to get that state child click and set child click of course you could have also solved this problem by using context or redux but in this video i wanted to keep it simple so now let's pass this method right here set child click and we're going to go back inside of our map we get that function right here through props and then finally what do we do we simply call the setchild clicked and we set that child right there now if we go back to the app when we call that function the child clicked variable is going to be populated and now we can pass it over to the list so we can say child click is equal to child clicked finally if we go to the list now we can do something with that value so in here child clicked and for starters let's simply cons a logit so i'm going to say kansa log i'm going to put the cons log inside of the object and in there i'm going to say child clicked if you put the property inside of the console log it's going to give you a bit more info if we did a console log just like this and by the way this is a great tip that i learned if you did a console log just like this and for example the value is 5. if you had a lot of cons of logs you wouldn't know what this 5 stands for but in the case above it's going to give you an object where it's going to say child clicked is equal to 5. that way you know exactly what your cons are locked so with that said let's see the output going back to the browser i'm gonna clear the console and reload the page one more time there are some warnings here which we're gonna fix later on but for now let's simply clear the console and now let's try clicking on a few restaurants if i click here you can see child clicked and that is 25. i can keep clicking i'm going to get 10 1 and so on this is not going to be extremely precise for example if i click at the title or if i click below at the rating it's sometimes not going to recognize it always try to click right in the middle of the image that way you're going to make sure that it's recognized as you can see we're getting a lot of these child click properties that means that we have the information about which element is clicked now that we have that info the question is how do we make our list scroll to a specific element on the list when we click on the map for that we're going to have to use react refs that's going to be just a bit more complicated but don't worry i'm sure you can do it first of all we're going to import use effect and also create ref from react so we're going to use that use effect right here use effect accepts a callback function and it has a dependency array we want to recall this use effect every time that the places change so i'm going to put the places right inside of here now we want to create a state field that's going to contain all the references so we can say const and let's call it something like l refs element references and we're going to say set l refs that is going to be equal to to the use state and at the start they are simply going to be set to an empty array because at the start we don't have any places once we get the places we want to set them to the state so how exactly are we going to create these references we can do it like this construffs is equal to we use the array constructor and then inside of there we want to construct as many elements as there are places so in there we pass the places dot length then we're going to call the dot fill that fill is going to start filling the array so we can call it like this and then we want to map over that array again we have a callback function inside of the map this time we're not interested in one specific thing at the start we only need the index in cases like these it's a good idea to put the underscore that means you're not going to use that first parameter but you need the second one and we want to return refs i so we want to access the refs and return that specific thing or if the ref doesn't exist yet in that case we can create ref so we want to create a new ref and this refs here is not gonna be like that because we are still declaring it in that line we have to use the l refs right there i know it's a bit more complicated but this is something you're not gonna do that often usually you're to have to create one ref in this case we really have to create many as many as there are places finally now that we have those refs we can say set lrefs is equal to refs now we can actually use those references right below here in place details so we're going to give each grid item a ref in this case that's going to be ref is equal to l refs and then we access that specific index of the current place and then we have to pass few props to place details remember what we talked about once we click on this element we want to scroll to that specific restaurant on the list so we're going to set the select property is this restaurant selected and how can we know that well if the child clicked is equal to index if that's the case that means that this place details has been selected this child clicked is a string though so we have to convert it into a number before we actually test it and we're also going to pass that ref by saying ref prop is equal to in this case l refs i so the same thing we did above we might not even need it later on in here i'm gonna check that to be sure but now we're passing the selected and the ref prop to the place details so let's use it right here we have the selected and we also have the ref prop we're going to use this to make a simple check we're going to say if selected in that case we want to call that ref prop and we're going to use the question mark dot notation each ref has the current property and then one more time question mark dot scroll into view that's a built in method on the element on the html element we're gonna put an object for options and we can say behavior is equal to a string of smooth and block is going to be set to a string of start this is everything that we have to do now that i think about it if we go back to the list we don't need this ref right there we are using it right inside of the place details let's save it and take a look we are getting an error saying that we don't at the start have the places and therefore we cannot create refs so this is the right opportunity to implement our circular progress which is the loading so let's go inside of our app component and then in here let's create a new state called loading so i'm going to create a new state field and i'm going to call it is loading and then set is loading at the start it's going to be set to false then right before we call the get places data i'm going to set it to true and finally after we're done fetching the data right here in the dot then we can set the loading or set is loading back to false finally now that we have this state we can pass that state over to the list by saying is loading is equal to is loading now we're getting it right here through the props is loading and just below this typography we're going to add a logical block saying is loading in that case we want to render a div dot div is going to have a class name equal to classes dot loading and inside of there we're going to have a circular progress which is going to have the size equal to 5 ram and otherwise we want to render everything else so the entire form control we can do it like that and make sure to close everything that's going to be just below our grid once we're closing it like this we have to wrap everything into a react fragment everything has to be inside of one element and then just below this grid ending tag we can also end the fragment and then end the code block okay i closed it correctly but in here i should have used a colon that part is done we're also missing a question mark right there because even though we're having a loading right there this part also is depending on the places so we're adding it right here and there's also one mistake i've made going into place details i have school into view instead of scroll so let's go ahead and fix that and finally let's take a look at that beautiful scroll in the browser there we have our restaurants and i'm gonna click and would you look at that our scroll works wonderfully we can scroll let's check out this one dolcini and it opens up nice our scroll is finally done the thing that would make sense to do next are these select elements which we've nicely created we need to be able to toggle between restaurants hotels and attractions and we need to be able to filter out restaurants hotels and attractions by rating to start filtering our places we can visit the source and then components and then finally list inside of here we created that type state and also the rating state now we're going to use the same method we used just a few minutes ago we are going to lift the state up as you can see we're going to copy this and move it into the app.js so right here at the top we have the type set type rating and set rating now we're going to pass these properties as props to our list so let's do it like this type is equal to type then we have the set type as well set type is equal to set type then we're going to have the rating which is equal to rating and then finally set rating which is equal to set rating now this is not the best practice ever we are declaring everything in our app and then we are passing it into our list as you can see we're creating a lot of states inside of our app and then we're passing everything as props through our components once again this is not the best practice but in this case it's just fine because we're passing it one level down only to the list but if we had one more component inside of the list which we needed to pass those props again from the list to that component or even deeper in that case i would strongly advise you to use react context but in this case this is just fine so let's go into our list and let's get these things from props that's going to be type set type rating and set rating and again the only reason why we're doing this is now in the app we have access to the ratings and to the types and now we can use them to get different data from our get places api so as the first parameter to our get places data even before the bounce we're going to pass over the type that way our function is going to know what data it needs to fetch so let's go to our get places data and then right inside of here we are going to copy this url and put it right inside of here instead of this static variable i'm going to turn this into a template string like this and now as you can see in here we have restaurants but in this case to make it dynamic we're simply going to get that type that we're receiving through the parameters that way if we have hotels it's going to be hotels if we have attractions it's going to be attractions this simple change made our code dynamic of course for this function to be reran when the type changes we have to add our type to the dependency array let's save it and go back to the browser here we have all the restaurants and if we switch to hotels notice that nice loading bar we added and here we have our hotels you might have thought that this is going to be so much more difficult we had to do a lot of work for the restaurants but now see how easy it is for the hotels we simply changed a variable and it works we can also now make it work for attractions again we have that nice loading and let's see what we can visit in berlin great this works perfectly this was a bit easier than we thought right now the next step is to fix the filtering based on rating to do that we're going to add one more use effect and you might be thinking wait is it even legal to have so many use effects and the answer is yes but every single one of them needs to serve a different purpose for example this one happens only at the start you can see it has this dependency array this one happens once type changes or coordinates or bounds but this one let's create it like this a callback function again and a dependency array this one is going to change only when the rating changes as you can see each one serves a specific purpose the only thing we want to do in here is say const filtered places is equal to places dot filter the filter method also takes in a callback function in this case we get a place and we're gonna say if place dot rating is larger than the current rating if that is the case then we want to return that specific place that means if the rating of the place is larger of the currently selected rating then we want to return that place finally we want to set these places to a new state so just at the top we can say use state and we're going to call this filtered places and set filter places and finally at the start that's going to be set to an empty array and right in here we can call set filtered places we're going to call it and pass in the filtered places variable great so now the question is where are we going to use these filtered places well if we have any filters then we can pass them to our map and also to our list we are already passing places so let's pass it right here if we have filtered places so we can say if there is filtered places dot length in that case we want to pass filtered places but else we want to simply pass places like this make sure to change it both in the list and in the map one more time if we have the filtered places then render the filtered places else just render the places then again every time that we get new places data we have to reset our filtered places so let's say set filter places back to an empty array great let's save it and check it out okay now we have restaurants let's go to hotels right now we can see all of the restaurants this one has four stars four stars and most of them have five stars but now let's click above 3.0 everything is still here and if we click above four you'll notice that now you can see only the best restaurants our filter works and if we go back to all you should be able to see all the restaurants now we know that our filter absolutely works so what would you say would be the next step in making this even more complete we already have a really really complex full-fledged travel advisor application what else can we do well don't forget our search is not working yet so if i wanted to go to new york for example right now i cannot do that so let's go ahead and fix that right now to implement our search we're going to revisit our header component we haven't been here in a long time as you can see in here we have this autocomplete component our autocomplete requires two props that need to be passed into it one thing is the on load handler so what is going to happen once we load the autocomplete component and then the second thing is the on place changed handler and what's going to happen once we change the place so let's implement these two functions right inside of the header component the onload is going to be fairly simple we can say const on load is equal to an arrow function and then in here we just want to return something more specifically we want to set something to the state so at the top we're going to import use state from react just below our classes we're going to initialize a new state field const autocomplete and set autocomplete that is going to be equal to use state and at the start that autocomplete is going to be set to null so what's going to happen on load well we're going to get that autocomplete we can call it auto c and we're going to set that autocomplete right in here so that we have it in the state and so that we can work with it this is the only thing that the onload function does finally we have to implement the const on place changed that's also going to be an arrow function but we're going to have just a bit more logic inside of it we need to find the latitude and the longitude of the new location we can do that like this constellat is equal to autocomplete dot get place we call that as a function dot geometry dot location and then finally dot lat and we call it as a function if you're wondering how i got to this information you can find it online or on google maps documentation but in this video i'm laying it out for you so that you don't have to waste hours finding it and now we can also find the longitude by simply saying lng right there and also position lng the question is what do we want to do once we get our new place well we want to set it to the state more specifically we want to go back inside of the app and change the coordinates we can do that by passing the set coordinates as a prop down to the header now in the header we can use that set coordinates and right inside of here we can call it set coordinates remember we set it as an object and we specify the lat and the lng this is all that we have to do with that specified our autocomplete should be almost done let's use this on place changed right here and right now you can see we misspelled the autocomplete so let's fix that auto complete and now everything should be fine but there's one thing that i didn't tell you and that is that if you take a look at this we are never actually connecting it to the google maps api we didn't input any api key or any such thing like that with this react google maps api we have to do it using a script tag in the public index html i'm going to give you the code for that script with all the other codes i gave you so far so make sure to copy and paste it right here the only thing you have to change is going to be this api key right here that api key has to be the same key that we are using inside of our map component right here so make sure to copy it and then paste it right here inside of this index.html once we did that we also have to keep in mind that this is using the places api no longer just the regular google maps display a map we have to get all the places on earth so we have to go back to our google developers console i am back on google cloud platform and you can see that we're currently using only maps javascript api so we have to go under apis if you're not here already and then finally let's add the places api there we go we can click on it and then finally we should be able to click enable there we go we're going to enable this places api and right now you can see that both apis are enabled let's try to go back to our application and see if everything works first of all i'm going to reload my page let's try searching for something like new york and if we click it we're instantly being teleported to new york all of the restaurants are here but they quickly disappeared that means that switching the map works but we still have some minor issues with fetching the restaurants depending on that specific location let's try to debug and fix that right away i also noticed that there are some empty restaurants with no ratings no name no image nothing so we need to be able to filter out those dummy restaurants to do that we can go back to our app and then as soon as we get the data we need to filter that data to remove these things so right here inside of set places we can say data dot filter we get a specific place right there in the callback function and then we simply want to check is there the name does this place have a name if it does does it also have the place dot number of reviews is larger than zero if both of these conditions are true then we want to keep that place also one important check is to only make this request if there are bounds so just at the top i'm going to say if bounce only then we want to do all of this code if we don't have the latitude the longitude the southwest and the north east we don't want to make this request and just to be sure everything is always going to work let's put a question mark right here in case we don't have the data let's save it and test it out in the browser there we go we can see all the best restaurants in london and finally let's switch to something like new york it loaded all of them but for some reason it switched back to restaurants in london in this list but on the map we cannot see anything let's inspect this even further by doing some console logs so i always want to know which ones are currently active places and also which are the currently active filtered places maybe that's causing the error so let's save it and now hopefully these console logs are going to help us debug this situation i deleted all of the console logs and i'm going to switch back to new york as you can see filtered places are empty which is fine we can try switching this to about 3.0 now everything is there above 4.0 still all of them are there and above 4.5 all of them are there because this api gives us only the best restaurants anyway but this time these restaurants didn't disappear so what was the catch the last time i just noticed that this if statement is not correct it's always going to be executed our bounds currently are said to be an empty object and an empty object is always truthy so rather than checking for bounds we can check for bounce.southwest and bounce.northeast if bounds are an empty object then this here is going to be falsy let's test it out okay as soon as i reload it everything works and now let's go back to new york we can see them on the map which works fine and hopefully they won't switch back this time i don't see them switching back so this was possibly the solution to our problem let's try to visit one more place something like paris to see if that works and unfortunately we still have restaurants from new york that means that we haven't properly reset the values of places when switching to a new place we can solve this problem really easily by simply removing the coordinates from the dependency array we need to do that because now in the header we are changing the coordinates and then they are being changed two times both in here on place changed and also on map right there so we're going to remove them from the dependency here and we only want to recall the get places data once we change the bounds if we now save this we can test it out and it should work we are currently in london let's try switching to new york we have a nice loading there and let's see if we get new york restaurants we do as you can see they're all there and let's try to switch to one more place something like paris and we got all the restaurants in paris our explore new places search now completely works now we can get the restaurants for our current position we can move around the map to get new restaurants each time and we can also use the search to get to any city or place on earth that was definitely a major feature the entire travel advisor functionality is now done user can visit different places get all the data about restaurants also hotels and finally attractions everything in one single place but wouldn't it be nice that they can also see what's the weather like there where they're visiting for example we're in france right now wouldn't it be nice if we could see what's the weather in this nice green park right here that's exactly what we're going to implement right now to find the api we need for that you can go to rapid apis hub and there search for open weather map this is the api we'll be using make sure to click here to subscribe to that api as well and from here we'll use only one single endpoint which is the search weather data back in our code let's close all the files and simply open the api index.js right below our get places data we're also going to export const get weather data and that's also going to be an async function and what do we want to do in there well we're also going to have a try and catch block if something goes wrong we're simply going to console log that error but what is the actual api request we'll be making well process is similar to the thing above we're going to say const the structure the data and then we want to make an await axios dot get call we have to see which url are we making the request to we can see that right in here url let's copy and paste that there we go and finally let's also copy these options the params and the headers i copy them i'm going to add a comma after the url and then open the options object inside of that options object we can paste all of the options we won't need many of these properties for example query we don't need that count we don't need that as well mode the only thing we need is going to be the longitude and the latitude so let's remove all of this and put this in one line like this so you might already guess where we would be getting the latitude and the longitude from right from our params right here lad and lng let's make sure that we indeed pass that so inside of the app.js we're going to import get weather data right here and then just before calling the get places data we're also going to call get weather data and we're going to pass the coordinates dot lat and also coordinates dot lng we can repeat the process we want to call the dot then we have a callback function that's going to give us the data and finally we want to say set whether data is going to be equal to data of course we haven't yet created the set weather data state so let's do that right away we can even copy the places and simply say set weather data and weather data at the start that's going to be equal to an empty array now that we know that we're passing the latitude and the longitude let's go back to index we're getting them right there and let's also set them so latitude is equal to latitude and lon is equal to lng in this case finally the headers contain our api key and rapid api host we can leave that for now later on we're going to switch that to environment variables and finally what do we do with the data well we're simply going to return it okay this part is done our data is here it's getting set to the state and finally we want to pass it to the map so just below i'm going to say whether data is equal to weather data right here we can go inside of the map we can get the weather data at the top from props and just below below the entire mapping of places we're going to open one more jsx block inside of here we're going to say weather data question mark dot list and then question mark dot map of course in here we get the data and we also get the index we mapped for quite many things in this video we're going to return ajsx block and for each weather data we are going to return a div that div is going to have the key equal to the index and it's also going to have the latitude which is going to be equal to data dot chord dot lat and finally we also need the lng lng property is going to be equal to data dot chord dot lawn and the only thing we need inside of that div is going to be our image our image is going to have the source equal to now bear with me it's a template string it starts with https colon forward slash forward slash open weather map dot org forward slash image forward slash w and then in here we want to use the dynamic value that we're getting from here data dot weather zero and then finally dot icon of course we want to add the dot png at the end this entire string is also going to be in all the resources that you can find in the description now i know we've been typing a lot of code let's save it and let's check it out in the browser and as you can see london is currently cloudy that's not unusual for london but these icons are too small so let's make them just a bit bigger i'm going to give this image a height which is going to be equal to 100. there we go now they're just a bit bigger let's go back to paris and see what's the weather in that nice park right there i'm not sure where it is there we go it just says that it's currently night with stars so now you know it's night here i'm recording these videos and i'm gonna go to sleep soon but with that said our weather data is actually showing as you can see it wasn't that hard rapid api makes it extremely easy to fetch apis and now you already know how to work with maps so it's also easy to display the icons and all of these cards great our application is looking so much better now the last part i wanted to show you is how to change the styles of the map we can do that really easily by going to map inside of these options we're going to have an object and that object is going to have a few properties first one is going to be disable default ui which is going to be set to true then we also want to have zoom control which is going to be set to true so this is going to disable most of the ui but we still want to have the zoom buttons and finally we pass the styles as map styles of course these styles are not defined so we are yet to do that but i want to show you an incredibly cool way that you can style the map extremely easily and immediately get all of the styles for your map there is a website called snazzymaps.com and in here you can see a lot of different maps that you can search for let's go with this one the only thing you have to do to get these styles for your map is click expand code and then simply copy all the styles into one file i already found my preferred styles so i'm going to put the styles here inside of the map say map styles.js and then i'm going to paste them right here again the link is going to be in the description now in the map we simply have to import these styles by saying import map styles from dot slash map styles that part is now done let's save it and take a look the styles i've chosen just gave everything just a bit more color and remove the names of streets now we have only the big city names and everything is looking just a bit cleaner one last step before deploying this application is set the environment variables so that nobody else can find your api keys the process of doing that is not that hard the only thing you have to do is create a dot env file right in the root of your folder if you're using github and you plan on deploying this project also add the env file inside of your git ignore that way all of your secrets won't be pushed to github with that said let's add these few variables every environment variable has to start with react app and the first one is going to be react app google maps api key and then you put an equal sign there then the second one is going to be react underscore app and then underscore rapid api weather api key and finally the third one is going to be react underscore app underscore rapid api underscore travel api key great finally we just have to find these keys in our code here is the google maps one and we're going to replace it inside of our environment variables right here just simply paste it and that's going to be it then once you actually have it in here the only thing you have to do is delete this and simply call process dot env dot and then the name of the variable in this case that's going to be react underscore app underscore google underscore maps underscore api underscore key i said underscore a lot of the times here but there we go now let's also find the remaining api keys which are inside of our api so that's going to be here this is the api key for the travel advisor app so i'm going to put it right here and finally the last one is for our weather api i'm going to put it right here and as you can see these are exactly the same i'm guessing that's because we are using the same rapid api account so the key can also be the same therefore we can simply rename this to rapid api key like this a lot shorter i won't have to mention a lot of underscores this time so let's simply rename this i'm going to delete first this string say process dot env dot and then react underscore app underscore rapid api underscore key and the same thing is going to happen right here process dot env dot and then the name of the environment variable one incredibly important thing to make this work is you have to open your terminal by going to view and then terminal and you have to stop it from running by pressing ctrl c and then y then you have to re-run your server for all of these changes to take effect so now when i rerun it all of the environment variables are going to be filled and as soon as you get back to our travel advisor as you can see everything works just perfectly now i know that this was a really long video and you have to get some rest definitely do that but i have a challenge for you next time you start coding come back to this application and find one more interesting api from rapid api platform i see there's airports flights hotels webcams just find one more api that can be implemented into this app and then try to implement it by following all of the guidelines you learned by following this video great with that said let's finally deploy this project to netlify netlify is great for deploying just simple frontend projects like this one so you can visit the netlify.com website and either sign up if you haven't already or log in once you're logged in you can click the sites right here and then go back to your code open up the terminal stop it from running and finally run npm run build this is going to create the optimized production build that you'll be simply able to drag and drop onto netlify and it's going to be deployed in a matter of seconds there we go it's built out you should be able to see this build folder and simply click reveal in file explorer once you have it simply scroll down and drag and drop it right inside of here in a matter of seconds it should say site has been deployed and there we go before we check it out let's simply go to the main settings and edit the site name something like travel advisor jsm should do the trick let's save it and let's visit it ok the website wants to know my location that's fine for you the geolocation should work and you should see all the restaurants near you in my case it opened up all of the most popular restaurants in london and you can simply browse through them and let's also go for hotels this one looks pretty good and finally let's see what can we visit in london there should be a lot to visit there okay national gallery the british museum and the westminster abbey great our application is fully done and with that we've came to the end of this phenomenal video this one took me quite a long time to make so please leave a like and comment down below what do you think of this one and what would you like to see in the future also huge thanks to rapid api not only for sponsoring this video but for creating such an amazing platform where you can find hundreds of thousands of different apis and if you'd like to build even more professional projects than this one make sure to put your email in the mailing list down below i'm gonna keep you updated about all of the new projects that will be coming along again thank you so much for watching this video stay healthy and see you in the next one have a wonderful day [Music] you
Info
Channel: JavaScript Mastery
Views: 168,231
Rating: undefined out of 5
Keywords: javascript, javascript mastery, js mastery, build a google maps application, google maps react, google maps react js, google maps api, google maps api places, google maps app tutorial, how to use google maps in react js, google places react, material ui react, rest api reactjs, rest api react, rapid api, rapid api javascript, rapid api react, travel advisor application, travel companion application, build a travel application, javascriptript travel app, react travel app
Id: UKdQjQX1Pko
Channel Id: undefined
Length: 132min 52sec (7972 seconds)
Published: Fri Aug 06 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.