Build a GitHub Jobs App With React Hooks

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey what's going on guys so today we have our second guest post on the channel and it's from kyle from the web dev simplified channel and his channel grew really fast in a really short amount of time and with good reason because he has a ton of great content everything from beginner html css videos to full stack javascript does a lot of react does full projects he does tips and tricks videos so definitely check his channel out i'll have the link in the description and today what he's going to do is build a react application from scratch and he's going to use the github jobs api so be able to fetch jobs be able to filter search implement pagination so if you're into react i think you'll really like this project and he'll tell you more about it so let's get into it before we dive into this project i want to give a huge thank you to brad for letting me on his channel because he was a huge influence for me when i was learning web development and also a huge reason why i decided to start my own channel teaching web development and i'm absolutely honored to be able to post on his channel now jumping into what you're actually here for the project in this video we're going to build out this github job api you see over here you see we have a listing of all of these different jobs these are all jobs that github has on their own github jobs page from over here we stick all jobs you see we have this listing and jobs it's kind of ugly so we've refreshed this made it look a little bit nicer we also have searching capabilities so i could say like nebraska for example and as you can see this is the only job available posted on this api that's from nebraska and overall we're just going to be making this nice clean design using the api that github has available which has the documentation right here and we're going to be doing this using react so to get started i ran npx create react app to give us boilerplate react code and i just deleted out all the testing and css files that we don't need and just left us with a single h1 that says hello world and if we come over here you can see we have that single hello world right here so we have just a blank canvas to get started with now the very first thing that i want to do is download the libraries that we're going to use to create the application you see here so let's just come over here create a new terminal tab type in npmi and we're going to need two different libraries we're going to need axios which is going to allow us to call the api we're using then we're also going to use react bootstrap and this is just to make styling easier for us as you can see we have all these bootstrap looking styles over here so it's just going to make it easier for us to get up and prototyping this design on the right hand side of the screen that you see here and now that that's finished downloading all of our different packages we can finally jump into actually doing the work that we need to make this design if i come over to this api and just zoom this in a little bit because it's really small hard to read text you can see that this is just the github jobs api and it has pretty poor documentation but in essence this git route down here is what we want it has our url for getting these different jobs as json and it's just going to return to us a huge json jump dump of all these different jobs so if we paste this you can see we're getting a huge dump of all these different jobs all the information we need as you can see we have some parameters such as description location and then up here we also have a page parameter we can use because this is actually a page in a paginated api so the very first thing i want to do is actually to write the code that's going to call this api for us because that's kind of the core of our entire application and instead of writing that inside this app component here i'm going to create a custom hook for that so we're going to create a new file called use fetch jobs dot js this is going to be our hook which is going to get all of our different jobs we just want to make sure we export a default oops default function this is just going to be use fetch jobs and inside of here we're going to take some parameters our first parameter is just going to be a list this is an object of all of our params so description location full time etc then we're also going to have another parameter here which is going to be for our page number that we're currently on now inside of the code we actually need to do a bunch of work to actually call the api save all of our different state and return the information that we need to the user to say where we are but before we do any of that let's go into our app and import that component we can say import use fetch jobs oops jobs from dot slash use fetch jobs so now we have access to that custom hook and down in here we can call that use fetch jobs we're going to pass it parameters and we're going to pass it a page for example page one for now we're just going to leave this completely blank we're not actually going to pass anything into here and what we want to do is say some variable is going to be equal to this like we need to figure out what information do we want to get from this hook here and when we're calling the api we're going to have a few different states we're going to have all of the list of jobs essentially this giant json dump so we're going to have our jobs being returned we're also going to have a loading state because while we're calling the api we're going to be loading the application so we're going to have a loading state and then we're also going to have an error state in case for some reason our request fails and we're not actually able to make the request we want to have some form of error state printed out to the user so let's come in down here and actually print out those different states we're going to do this inside of a container from bootstrap so we can just say import container which is a gear element that we can use from react bootstrap we can say react bootstrap we have this container component and we can just say container like that and now everything we put inside of container here is going to be inside of a bootstrap div that has the class container essentially so we can say for example if we are loading then we want to just have an h1 which is just going to have the text of loading let's do a similar thing for error but this h1 instead of saying loading i'm just going to say error try refreshing there we go and then lastly we're going to have our actual jobs for now we'll just say jobs.length we're just going to print out how many jobs we have to the page let's just put that inside of an h1 as well this is just temporary so we can actually see what's going on make sure we put that inside of the curly braces here we don't need these outside ones so that's just our basic code and now we have our jobs loading and error being returned from this use fetch jobs so instead of here if we were to return something for example an object where we set jobs equal to an empty array loading to false and error to false we should see zero being printed out to our app because we have zero jobs in the list we set loading to true oops true and safe you can see it says loading here and if we set error to true and we change this down to false for example you can see we get error try refreshing and we still have that job length being printed out of zero if we put some jobs in here for example just some random numbers we'll get three because there's three jobs in this list so really basic code everything we have so far is hooked up and working properly the next thing that we need to do is actually make this use fetch jobs hook do something because obviously returning this static object is pretty useless so let's come in here we're going to import use reducer we're going to import this from react we're going to use this reducer here to handle all of the different state inside of our use fetch jobs so we can just say con state and dispatch is going to be equal to that use reducer and this reducer is going to take a function which is our reducer function and it's going to take an initial state and by default our initial state is going to just be an object here we're going to have an empty array of jobs and we're going to have loading be set to true because by default we're going to be loading our object at the beginning just like that expand my screen a little bit you can get that all in one line and now we have our state and our dispatch and our default state we just need to create this reducer function so we can say function reducer and this is going to take in a state and an action and essentially what happens with a reducer is this producer function gets called every time we call dispatch and dispatch whatever we pass to it is populated inside of this action variable and state is just whatever our current state of the application is so if we were to for example say dispatch and we set this an object that had a type of hello we for example had a payload which had a value for x of 3. now inside of here we would have action.type which would be equal to hello and we would have payload dot x and that would be equal to three so essentially whatever we pass to dispatch goes into action and then our state is obviously just our state and a common convention is to set a type for our different values our different actions we can perform and then payload is the data for that type so in order to define all of our actions we're going to create just a constant variable called actions and this is going to be set to an object which defines our actions so that we can reference them later so inside of this use fetch jobs we have a few different things we can do we can make a request so we'll just say set that to the string make request another thing that we can do is get our data so when our request finishes it's going to get our data from that request so we can have git data which is just going to be the string get data and the last thing we can do is if we have some form of error so we're going to have a state called error with the string error and these are the three different actions that we can perform on our state and now in our reducer we can just set up a simple switch statement based on our action.type and inside of the switch statement we can do this different switch for each one of our actions so actions oops if i can type today actions dot make request and then we can do some kind of stuff in here we can have another case which is going to be for actions dot get data and then we're finally going to have a case for actions.air and then lastly we're going to have a default and this just says if we pass in an action type that we don't have inside of our list we're just going to return our current state we're essentially not going to update anything now when we're making a request we need to return a new state and this state is actually just going to be a hard-coded value where we set loading oops loading to true and our jobs is going to be set to an empty array so every time we make a new request we essentially say that we're loading and we clear out all the jobs that we currently have now when we're getting data we're going to be a little bit different we're going to take everything that's in our current state and put that in our new state but we're also going to come in here change loading to false and then we're going to need to set our jobs to something so we can say jobs whoops jobs is going to be equal to action.payload.jobs so we're going to pass our jobs in on the payload of our action and set that inside of our action.getdata now for our actions.air this is going to be again very similar we're going to take our current state we're going to spread that out over the entire thing we're going to set loading to false and our error is just going to be action.payload.air so we're going to pass our error object in and then lastly we don't want to have any jobs so we're going to clear out our jobs if we have an error so that's all the different actions taken care of now we can work on writing the code to actually call these different actions so let's clear this out and what we need to do is every time we change our parameters so for example anytime we change one of these fields up here we need to reload our page like this or if we change our page number so if we go back here and we actually click one of these arrows to change our page number to example page two you can see that we need to repopulate our data so anytime we change page or params we need to run our code again and the best way to do that in react is using the use effect hook so we can get this use effect hook come down here say use effect which is going to take in a function and then our parameters the things that we want to happen so whenever these things that we passed this array change for example whenever our params or a page change then we want to rerun this use effect hook now inside of this hook the very first thing we want to do is call dispatch and we're going to call it with a type of make request so we're going to say actions.make request because we're making a new request and this doesn't take any type of payload it's just a single type and what that's going to do is it's going to update our state right here like we set it to do so now that we've set our state to essentially our loading state what we can do now is actually call axios and since we need to make sure we import axios let's just import axios from axios and we can say axios.git this is going to make a git request to this github jobs api i'm just going to copy this url here this jobs api and i'm going to paste that into here but instead of pasting it directly here like this i just want to create a single variable for it we're going to say base url and we're going to set that here to this jobs api and then we can take this base url and put it in here this will just clean up our code a little bit now once we have that we need to pass it a bunch of options the first option is going to be our params in our case we're going to pass it our parameters here we're also going to pass a couple extra parameters for example you can see here we can set markdown to true and that'll return all of the different description fields and such that you see here with all these characters it'll return them in markdown instead which is going to be easier for us to work with so what i want to do is i want to say markdown is going to be set to true we also want to set our page equal to our current page number then lastly we just want to take all of our current parameters and we want to put those inside of our params as well so for example description location and full time that's what this params object is going to contain and we're going to just pass all of those as our parameters now with that we can call dot then and this is going to give us a response and this response is going to have some form of data res.data and this is our list of jobs that's this json right here that we get back from the api and we can call that dispatch function so we can say dispatch we're going to pass an object with a type and our type is actions dot make or i'm sorry get data and we're going to have a payload here which is going to have our jobs and these jobs are just that res.data so let's just copy that in like this now we essentially have made a action here we're saying okay we got our data so let's save our data to our state by calling the get data action and then if we have an error of some time we need to catch that so we're going to come in here with our catch and we're going to do a very similar thing but instead of get data we're going to be calling the error action and instead of putting our data in here for our jobs we're going to have error which is just going to be equal to our e here so we can store whatever error we got now if we save this we should have everything working to order to call that api and now down here we can return our state instead of returning something else we're now just returning this state and if we save come over here you're going to notice we get an error and the reason for this error if we inspect our page go over to our console tab you'll see that it says access to you know this url from origin localhost has been blocked by cores so we're running into a course issue and this is generally really annoying to get around because you need a server to act as a proxy for cores in order to get around cores but luckily there's a service that we can use in development in order to get a round course that someone posted up on heroku and it's this url https only backus backdress cores anywhere.heroku.app and essentially if we just put this in front of our url it acts as a proxy for us so we don't need to create our own proxy server and it's actually going to get around cores for us so we'll just put that in front of our url here now if we save and you see we get our loading state and it's just going to be constantly loading until now it loaded and we have 50 different things being returned because this api is paginated and it only returns 50 results at a time so we now have the first 50 jobs inside of the jobs portion of our state here now that's great but there's actually one problem with this code it's a really minor problem if for example our params change really really quickly we don't want to have a bunch of different calls to this api go out all at once and then come back all in different orders so for example over here if i were to start typing in my location of nebraska i don't want to have tons of different axios requests going out there and being out there the entire time i wanted to essentially just stop making these different requests whenever i type in a new character so whenever our params change we want to cancel the old request so in axios it's actually pretty simple to do that we're going to create a cancel token which is just going to be equal to axios dot cancel token and then we just need to say dot source and this is essentially going to get us a new cancel token we can use and we can pass our cancel token here by saying canceltoken.token to get the actual individual token itself so now we have a reference to this access request inside of this cancel token and now in order to clear that out inside of our use effect if we do a return down here it'll run a function whenever we essentially change one of these values down here it's going to run that to clean up our old code here so now this function will be ran and we can just take our cancel token and we can just cancel this by calling the cancel function the only thing we need to worry about is when our request is cancelled it's going to call the dot catch portion so we need to check here to see if this is a cancel so we'll say axios dot cancel i'm sorry is cancel and we pass it the error so essentially if this was a cancel the request all we want to do is return here this isn't actually a real error this is us purposely canceling this so we're going to ignore this error and only track errors that occur not because of canceling and now if we save we should still see loading and then 50 so everything is working as expected now the next thing to work on is back in our app now we need to actually pass in our parameters and our page so we need to have some param here and some page so let's just create state for that we'll just import use state here from react and we can say params whoops params and set params it's going to be equal to use state we're just going to have that default to an empty object and then we're going to have the same thing for page and set page but we're just going to have that here be set to page 1 by default so now if we save hopefully everything works just the same as before and you can see that it does now we can work on instead of printing out our jobs.linked let's actually print out each individual job so we can say jobs.map loop through each one of our jobs and now inside of here all we need to do is return a job essentially we need to return the html to render our job card which you can see over here and if we just clear this out we can kind of see what a bunch of them look like as you can see here and this is actually fairly straightforward we're going to create a new custom component for our job card so we'll create a component which we're going to call job and in this job component we need a key because it's inside of a loop so the key here is just going to be job.id and then we're going to pass the job down like this so now we have access to all of our job properties inside of our job and we also have the key so that react knows how to properly render this and if we save we're going to of course get an error because we don't have a job component yet so let's create that job component inside of our source create a new file called a job.js and i have an extension installed which is called react es7 redux graphql react native snippets it just allows me to type in here rfc and hit enter and that's going to generate the boilerplate for a function component you can type this all out by hand or download that extension it's entirely up to you so now with all of that done we know that the only prop being sent into here is our actual job itself and for now all i want to do is just print out our job dot title this is essentially the title of the job we'll be getting just to see if this is working now if we save this refresh you see that we're getting another error saying job is not defined that's just because we need to make sure we import job so let's import job from dot slash job and now when we save you should see we get a list of 50 different job titles based on the first 50 jobs inside of the api and you can see that this actually lines up with the job titles over here so now the next thing to work on is actually creating these different styles because this is obviously very ugly so let's make it look a little bit more like this over here where we have each individual card so inside of our job we need to import some components from react or from bootstrap i'm sorry so we're going to import card just to get started from react bootstrap oops react bootstrap and this is going to be what we can use to create our card component so instead of here having this div we're going to trade this out with a card just like that and inside of our card we're going to have a body so we'll say card.body and in the body is we're going to put all of our different code for our card layout like this now the very first thing we have is we have this left hand side which has all of this different information and then just this right side right hand side here has the image as you can see all of our card follows that exact formula where we have everything on the left and then the image on the right hand side so in order to do that we're going to inside of our body create a div with a class name here of d flex we're going to just justify content between and in this div what we're going to do is on this first element inside of our div we're going to put all of our content on the left hand side and the second part of our div will put the image and that'll space them out side by side just like we want so let's first start with our div which will contain this left hand side content so we'll create a div here and inside this div we're going to need our title first so we're going to say card.title and inside of here we're going to put this job title so we're going to put our job title up there and then inside of here we're also going to put our code for this company as well we can just put a single hyphen here and then we're going to create a span and the span is going to contain all the code for making this a little bit lighter colored so we can just say class name we're going to be equal to text muted font weight whoops wait light and what this is going to do is essentially make this a slightly lighter color of text and it's going to make it a less like bold font as well so now we can just put the job.company in there which is coming from that api and if we save come over here you should see that now we have our information being printed out where we have our title and we have our actual company here but you'll notice none of these bootstrap styles are being applied the reason for that is we need to import bootstrap into our app and to do that we're just going to go into our public folder here our index.html and if we go to the react bootstrap page you'll see that they have this link here we can just copy under how to use css to import bootstrap if we just paste that into here this is going to give us a reference to bootstrap which we can load in our page and now we save come over here you see that we have bootstrap styles being applied you can see we have our cards we have our different font weights our titles everything exactly like we want it obviously spacing and everything is not quite right yet but we're working on that so now we can move on to styling the rest of our card as you can see here we have the next thing being our date so let's go back into our job we have our title done so now we can move on to the subtitle which is going to be our date and inside of our subtitle all we're going to do is print out a new date which is our job dot rated at and unfortunately this api uses underscores for everything instead of camel case so it looks a little ugly in javascript but that's just how the api is and we needed to deal with it so we're converting this created at to a date and we're just going to convert that to a locale date string this is just going to put this date as a string in whatever locale the current person viewing the page is looking at it in so for me since i'm in the us everything is going to be month then day but for example if you're in another country it may say day then month and let's do a little bit of styling to get our text like we want it so we'll come in here with a class name we're going to say we want this to be text muted we're also going to put a little bit of margin on the bottom to give us some space between this text and these little badges down here now if we save from over here we should get that date showing up that's exactly like we want it and now we can work on those different badges and those are actually fairly straightforward we're just going to use the badge component from bootstrap so let's import that badge component and inside of this badge component we just need to put our text so the first thing we're going to have is our job.type this is going to be full time part-time or other things like that and we're going to have another badge which is going to be nearly identical but this one is going to be for our location so as you can see over here we have you know bucharest and we have new york city beretta and so on so we have those different badges and we want these badges to have a certain variant so this is like primary info danger warning if you're used to bootstrap you're used to those different words and for us we're just going to use secondary for our variant and we'll just copy that down to the other badge now if i save come over here you should see those badges populating but they're right next to each other i kind of want to space them out so let's come on this first one we're going to give it a margin on the right of two and they'll give us a little bit of space between these different badges and that looks really good now the next thing we can work on is this how to apply link here and this is actually sent to us in markdown because as you can see these links are different across all of these different applications it's just marked down that the person making this job typed in themselves we need some way to convert this markdown to react code and luckily there's a library we can install by typing in npmi called react mark down and then this is going to let us do is essentially convert this markdown that we're getting sent from the api and converting it into react so we just want to make sure we import that so we can say import react markdown from react markdown just like that and now underneath this badge let's just create a div and inside of that div let's put this react mark down and all this is going to have is a source and the source is going to be equal to job.how to apply again with underscores unfortunately and if we save come over here refresh our page you should see that we now have these links showing up but they're going way off the edge of our page as you can see we want these links to wrap if they go to the edge of the page like this which is why we have this div we're just going to give this here a style of word whoops word break we're going to set that to break all now if we save we should see that these wrap just like that which is exactly what we want now this is everything that's going on the left hand side of our card let's just kind of collapse this div to make it easier to see what we're working with or create another div and this is going to be for the right hand side and we actually don't even need a div for this we're just going to use an image tag here we can just close off that image tag like this this image tag is going to be for our company logo so we can say that our source here is going to be equal to job.company oops underscore logo and let's make sure we put an alt on this so people using a screen reader can read this we just put the company name as the alt so job dot company just like that so now we have our alt tag as well as our source and let's just put a couple different classes on here to make sure this doesn't show up on super small screens so we're going to say class name is equal to d small none this means it will be hidden on small screen sizes and then we'll set d medium block which means it's going to be shown on larger screen sizes and then to make sure this image is never too big we're going to set the height equal here to 50. and this should actually be extra small here i'm not i'm sorry not extra small should just be d none that means it'll be hidden all the time but on screen sizes medium and larger it'll be showing now if we save this we should see images showing up on the right hand side here and if we shrink down our screen size you'll see that they disappear when it gets to the small size and the extra small size but when we get large enough you'll see the images pop back up and it's never taller than 50 pixels which is exactly what we want now just going back up to the top here what we can do is close down this complete div since this is essentially all of our left versus right hand content section we can go down we can work on our next little section which is going to be this view details button as well as the actual details of our job listing so in order to create this button we're going to wrap this in a card.text this is essentially just a way to write text inside of our body it's going to give us some nice spacing and we're going to need to create a button so we're going to import the button component from bootstrap just like that we close off this button and this will just say view details for now and this button we also need to specify a variant for in our case we're going to use primary as the variant for our button now if we save go over here we should see we have that view details button which is exactly what we want now we can create our details section let's just create a div with a class name which is going to be mt of four we're just going to put a nice large margin on the top of this section so it'll space it away from our button and then again this description is in markdown so we're going to use react markdown pass it a source here which is our job.description close this off now if we save we should have our description showing up just like this but obviously clicking this button doesn't do anything so we need to create the functionality for showing and hiding our button and we can easily do that with the collapse component so let's set this collapse component here and we're going to wrap this entire thing inside of a collapsed component let me just move that down there we go now that's all inside the collapse component and this is just going to take a single property called in and we're going to set that to a variable called open so when this open variable is true collapse is going to be open and when it's false the collapse is going to be closed we can just use state for that so we're going to say open and set open is equal to use state and by default we do not want this to be open so let's make sure that we import use state use state just like that and now everything should load just fine like i did before there we go and now we can work on setting our set open and our open which is going to happen when we click on our button so we can say here on click what we want to do is just set whoops call function which is going to take set open it's going to take our previous open and it's essentially just going to invert that so we'll say previous open just get this on a new line so it's easy to read there we go this makes a little bit easier to work with like that and now you can see just immediately by doing that our details are collapsed and we click view details it'll show and when we unclick it'll hide them but having this save view details the entire time doesn't really seem right it should change from view details to hide details when we click on the button in order to do that we can just simply come in here and say if open is true then we want it to say view details otherwise if it's false we want it to say hide details and now depending on the state of open versus closed oops i have that backwards this should be i details if it's open and it should be view details if it's closed obviously and now you can see view details and when it's open it says hide details so we can toggle each one of these individually and that's working exactly as we want now let's add a little spacing between our cards we'll just come in here say class name is going to be equal to margin bottom let's say three that should give us some good space in between our cards that looks pretty good and also let's give a little bit of spacing on the top and down here all the way on the bottom of our container so what we can do is just say that we're gonna have a class name on our container which is a margin y and we'll just say maybe four for example that gives us a little bit of space from the top and the bottom of our container so right now we have the basic shell of our application complete so let's work on the next step which is going to be our form input up here as well as our pagination and actually before we get to that let's add in this little nice title which we can just put here which says h1 github jobs and also we can change our background to this nice color if we just go to the index scroll down here till we find our body just like this we can set the class here to bg light and that's going to give us this nice little white background color to make our cards pop a little bit more if we save our app here we should get that github job showing up at the top as well also let's space that out a little bit let's give it a nice class name here we'll say mb of 4 just again to give it some space underneath for the loading and our cards to populate themselves so now let's work on our pagination so our pagination is going to be this list right here we can just create a component for that we're going to call it jobs imagination dot js and again we could do that rfc trick to create the component and here we're going to need our page that we're currently on as well as a function for setting our page and those are going to come inside of our props for this component now luckily with bootstrap we have the ability to just use a component called pagination just like this and we're going to import that from react to bootstrap and now instead of this div here we can replace this with pagination and this pagination component has things called pagination items pagination previous project nation next which is going to give us all these nice little icons so we can for example say pagination dot previous and this is going to give us the icon which is going to be the left pointing back arrow if i just delete this real quick save this and in our app we actually render that so let's just make sure we put that here directly before our loading text we'll say jobs imagination that auto imported up here for us and we need to import our current page into this so we can just say age is equal to age and set page is obviously equal to set page we want to put this at the very beginning of our list and all the way at the bottom of our list so we can save like this and it's going to refresh and you can see now we have that back arrow showing up at the top and we also have the same background showing up at the bottom so we have this nice little back arrow you know showing up exactly where we want it at the beginning and the end of our list now we can add in pagination for example which we'll do next and this is going to give us the forward-looking arrow like that and then obviously we need to have pagination for our different pages so we can say pagination dot item this is going to be an item so we could say for example page and this is going to be our current page we can do page minus one to get our previous page and we can do page plus one to get the next page we say that you can see that looks like this obviously it doesn't make sense to have a zero so we want to have some checks in here because if there's no previous page there's no point in rendering this previous arrow so we can say if page is not equal to 1 then we can render this so essentially if we're not on the first page then we have a previous page so let's render it same thing down here we obviously don't want to render this previous page look if we already have a page of one so now if we save immediately you see that zero and that back arrow have disappeared which is what we want we go back over to our other app you'll notice if we go to for example page two we have our background we go to page three you'll notice something else we have this little dot dot dot section which essentially lets us always jump back to page number one and this is actually pretty simple to do with bootstrap we have something called pagination.ellipsis and that's going to give us this knight dot dot syntax we only want to render this dot dot dot if we're already on a page past number two because then we can jump back to number one we're going to say here is a page is less than two i'm sorry greater than two then that means we're on a page after two so three four five and so on so then we can render this ellipse and also if our page is greater than two we wanna render an item and that item is going to just have one in it at all times so close that off and this is essentially the ability to go back to page one all the time now let's move this page minus one down to here we need to change around our if statements a little bit so we only want to render this one if we're not on page one already this is not equal to one then we're going to render page one and here we only want to render the previous page if we're greater than two because we're already going to have one rendered up here so if we're on page two this would have one then one then two so i can show you what that would look like if we just did not equal to one and i saved i came over here and we clicked on for example page two or if our page was two so let's just say i go to our app and i set our page to two by default you'll see it says one one two and the way that we get rid of that is by just making sure that this is only shown when it's greater than two now if i save you can see we get that one two three which is exactly what we want let's of course go back to page one by default and now the next thing that we need to do is to make sure we set this page right here as our active page so we can just say active and that's going to set it as active so we can see that we're currently on page one it does not let us click that and we can only click all of these other page icons here also something we need to do is to check to see if we have a next page we're going to have a variable called has next page and if that is true we're going to render this item for our next page and we're going to do the same thing down here we say has next page then we're going to render this pagination.next and the reason for all of this is that we don't want to render the next button if we're already on the last page so now if we save and we imp but here has next page we should see all those next icons are disappeared because we have not set this to true yet but if inside of our app we come down here to pagination we pass has next page equals true to both of these different components you'll now see that we have those next items showing up so how do we actually calculate what the next page is going to be well this is actually something we need to do inside of our use fetch jobs hook because unfortunately this api doesn't actually tell us if there's a next page or not we just need to manually check to see if there is another page and if so we need to update a variable that says so so we need to add another action this action is going to be for updating as next page so we can just say update as next page we just say update has next page and now instead of here we can create another case which is just going to say actions dot update has next page and we're going to return our state as well as as next page we're going to set that equal to our action.payload next page so we're just going to pass true or false whether there is a next page or not to this update action so now let's actually figure out how we can use that action well the easiest way to do it is essentially just do another access request for the next page and see if there are any results i'm actually going to copy essentially all of this code so we're going to create a new axios request but instead of page we're going to go to page plus one and then if we have a successful result here what we're going to do is we're going to update our has next page and we're going to set the payload essentially equal to as next page and it's going to be equal to if this data essentially exists so if the data dot whoops dot length is not equal to zero that means that we have some data on the next page so we do have a next page so it'll be true but if the length is zero that means there's no jobs on the next page so this is going to be false we can still do the exact same thing down here with our error we need to create a separate cancel token for this because it's a separate request so we're going to have up here cancel token 1 change this to cancel token 1 and cancel token 1. now let's just copy this cancel token and we'll do cancel token 2 cancel token 2 and then down here cancel token2 dot cancel just so we have two different cancel tokens and we can individually cancel each one of these requests so now we have this has next page inside of the state coming from use fetch jobs and if we go over to our app and we just take that out here as next page and now instead of just hard coding true we just pass in that has next page variable and we save you can see that it's going to load and it says that oh there is more information on page number two which is exactly what we want but now we need to make it so when we click on these it actually updates our page so inside of this jobs pagination i'm going to create a simple helper function that we can use to get started with so we can just say that we want a function which is going to be called adjust page we're going to pass it in an amount and all this is going to do is set page equal to the previous page we just want to take the previous page and we want to add in the amount this is just a nice little helper function that will allow us to update our page based on an amount whether it's negative 1 positive 1 and so on so in our previous on click oops on click all we want to do is call that function of adjust page and we pass in negative one because we're going back one page on here we're always going to page number one so we can just say on click we're going to come in here and call set page we're just going to set it to one because we're always going to page number one here we're doing the exact same thing it's the previous page so let's just copy this in this is just going to go to the previous page and we click this one down here we want to go to the next page so we'll use a positive one and for next we're going to use positive one because we're going forward one page now if i save this and i click on this two here you should see that we go to the second page of results and it's loading in click three we're going to the third page of results click one we're gonna go all the way back to the very first page of results and so on so now we have our job cards done we have our title done we have pagination done the last thing to do is to work on this form here actually querying the different parameters of our api so in our app.js this is going to be where we take into account this params here which so far we haven't used yet and in order to do this we're of course going to create a new component which we're going to call searchform.js rfc and we have our boilerplate code here and this is going to take in our params as well as some variable for updating them which we'll call param change so now before we go about actually writing the code for our search form let's implement it into our app so we can come down here and we can create first the function for updating our params we'll call it handle param change this is going to take in an event and this event is going to come from our input so every time we change our event it's going to send this function here it's going to call this function so we can get the param we want to change by just saying e.target.name whoops and we get the value by saying that's e.target.value and then all we need to do is set our page to one because obviously we need to go back to page one if we reset our you know parameters so if we search for something we obviously want to search on the first page and not the fourth page and then we want to set our params and we're going to take into account our previous params return here a new object where we take all of our current params so all of our previous params plus we want to set whatever our new param name is we're going to set that equal to our value so this name here for example will be description and we're going to have a key inside params called description which this is going to access and we're going to set it to the value which is whatever we type into this description box here and this handle param change is what we want to pass down to our search form so let's put our search form in here we'll say search form that automatically imported that for us and then we can just say here that we want to have our params equal to params and our on param change is equal to handle param change and that's everything we need to do to get our search form rendered on our page so now if we return for example hi here you should see the text high is going to show up right there which is exactly what we want but obviously the text high is a little ugly so let's create an actual form to do that we're again going to use bootstrap we're going to import the form component from react to bootstrap so now inside of here let's just take our form we're going to set class name equal to mb4 just give us a little bit of spacing underneath of our form and now we're going to create a row so we just say form dot row and inside of here we're going to create a bunch of different form dot groups but we want these form groups to essentially act as columns inside of our row so we can just say as call here and all this is doing is essentially saying render this form group as the column component from bootstrap so we need to get that column component imported just like this now instead of our form group we can create a label form.label and we're just going to say description and we're going to need an input for that so we'll say form dot control this is how you create an input with this react bootstrap library our on change function is going to be that on param change so whenever we change this control it's going to call that function that we created earlier we also want to set the value equal to params.description oops make sure i spell that properly there we go and we also in order to make this on-prem change work we need to set our name here equal to description which is exactly the same as the value inside of this params object so now if we just close that off set our type to text and we save we should see that we now have that description field showing up and whenever we change this it's going to change our params so if we for example search for let's just say that we want to search for azure oops azure now we see that only things that involve azure are actually showing up in our list of results so if we viewed our details here there's going to be something about azure here something about azure and so on we're able to limit our results to only azure in this case let's just copy this form group because we're going to do almost the exact same thing but instead of description we're going to have location so we're going to change this to location and we're going to change our param to location now if we save you should see we have two text boxes and we type in for example a location like we typed in nebraska you can see we get the only company in nebraska that has a job listed on this api and if we delete it you can see we should get back all of our different job listings now the last thing we have is one more form dot group and this one we're again going to make act as a column but we actually want to do something slightly different and that we're going to set extra small to auto and that means that instead of being equal width for example this is half the width this is half the width if we create a third column each of them would all be one third of the full width this is just a checkbox we want it to be as small as possible so auto essentially says make this checkbox take up the least amount of room as possible so it doesn't take up a full third of the column it's just going to take up the least amount of space possible we're also going to set a class name here which is ml and that's going to be 2. we're going to put a little bit of margin on the left-hand side of it to space it out from this location since it's going to be as small as possible now we can say form.check that's how we create a checkbox we're going to do a lot of the same stuff we're going to set our on change equal to that on ram change our value here is going to be equal to params.full underscore time because that's how this github api expects it to be full underscore time it kind of sucks but we just have to do it same thing with name we need to set that to the exact same string full underscore time and this one we need to set an id to full time and that's just so we can link our label up to our actual checkbox and speaking of label let's actually set our label to only full time and this will just give us only full-time jobs and lastly this is going to be a checkbox and we can close this off now if we save you can see we get only full time showing up but it's kind of in a weird position it's way up high for some reason so instead of a row here let's set a class name which is align items end and that's going to push everything to the bottom but you can still see it's not quite centered with our text box and an easy way to fix that is we can just set a class name here of margin bottom 2 on our checkbox and it's going to put a little margin on the bottom which lines it up pretty much exactly dead center now when we click this it's going to reload and it's only going to show us full-time jobs unfortunately most of these are already full-time jobs so it's hard to see it working but i promise you that this actually works and that's all there is to creating this jobs api page again i want to say a huge thank you to brad for letting me on this channel it's an absolute honor to be here talking with you and i really hope you enjoyed this video thank you very much for watching and have a good day
Info
Channel: Traversy Media
Views: 120,369
Rating: undefined out of 5
Keywords: react, react app, react tutorial, web dev simplified
Id: fxY1q4SCB64
Channel Id: undefined
Length: 48min 47sec (2927 seconds)
Published: Mon Jul 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.