Dogs, JavaScript & An API 🐶 Fetch, Promises & Async Await

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back to the bootcamp series uh this is gonna be maybe a long video but i think it should be a fun video so before i talk at all i wanna show you a sneak peek i wanna show you a sneak peek preview of the finished product that we're going to build together so you open the app and it says choose a dog breed and then when you select one it shows you a slideshow the images sort of animate or fade or transition in between each other and then you're free to choose a different dog breed and obviously get a new slideshow now what makes this interesting is that none of these dog breeds and none of these images are actually spelled out or hard coded in our html or javascript instead we're fetching all of that data programmatically from another server out on the web and this is all thanks to the javascript code that we're going to write now hopefully you did a little bit of homework and checked out the 10 days of javascript because if you didn't there's going to be parts of this video that maybe feel like we're moving too fast or we're not explaining every concept if we stopped to explain every concept this video would be two or three hours long and i don't think that would be enjoyable for anyone there are already a ton of different videos on the web explaining the very basics of javascript and then there are also a ton of videos that show you super advanced things but i don't think there are enough videos that are sort of the goldilocks level of difficulty what i mean is relatively basic but complex enough that you're still actually building something that's exciting anyways that's enough with this introduction i'm excited to build this slideshow with you so let's jump into the action okay so in vs code i'm working with a new empty folder i've created just one brand new empty file index.html inside it i'll say doc and then hit tab inside the body area let's just say hello world for a bit of placeholder text and because our focus in this video is javascript let's begin by attaching a javascript file down here right before the closing body tag so we just say script hit tab on the opening script tag we just say src or source equals quotes and then we just point towards a file you could name it anything but i'll name it main and then we want it to end with dot js so this will point towards that file let's go ahead and save this now we need to go actually create that file so in my folder new file i'll name it exactly main dot js okay now just for a quick test to make sure that our javascript file is actually being loaded we can say console.log parentheses to call that give it a string so just quotes and say hello from our js let's give that a save and now let's go view our html file in the browser so if i refresh cool there we see hello world and we can check out the javascript by right-clicking and choosing inspect that will open up your dev tools and then instead of elements if we click on console cool there we see hello from our javascript so now that we're up and running right we have a basic web page and we've attached a bit of javascript what do we actually want to do first with our javascript code well if we look at the finished product example i think the first thing we should do is create this select or drop down element that you can click on and then it shows you all of the different breeds of dogs now what makes this interesting and sort of the entire point of this dog app is that i didn't hard code this list of breeds what i mean is if i view the source for this html that select drop down element with all of the breeds it lives in this div that has an id of breed so that actual list of breeds doesn't live in our html and i can click here to look at the finished product javascript nowhere in this code will you see a giant list of dog breeds either so the question is where is all of this data of these breeds coming from well it's being pulled dynamically from another server out on the internet somewhere so right now let me talk a little bit about how i found this magical server with dog information so there's this really popular page on github called public apis don't worry i know we don't know what an api is yet we'll talk about that in just a moment but this page lists all sorts of different apis which give information about different things so there's ones for animals right and you can see this list just goes on and on finance health music but if you click on animals there's this one called dogs and i just clicked on that okay and that takes me to this website the dog api now before i show you how we can use this website and use its data in order to build our product for this video i first want to talk a little bit about what an api is because that's a phrase i've been throwing around and in this bootcamp series we've never heard of that yet well if you jump over to wikipedia you can see that api is just an acronym that stands for application programming interface and you could read all about this if you want to but in short i would say that an api is just an organized way for one application to communicate with another totally separate and different application so for example this application that has all sorts of information about dogs well they've created an application programming interface for their app and now we can communicate or work with their data from within our application right we can programmatically request data from the dog app or from the dog api let me show you how this works so from this dog api website from their homepage they have this url here and if you copy and paste this url and open it in a new tab you can see it gives me a bit of raw code and it says message colon and then here's a value and this is just a url for a dog image you can see it ends in jpeg and every time i refresh it gives me a new random dog url this is because if we look at the address bar this specific url is designed to give you one random photo okay but back on the actual dog api website if i click on documentation in their sidebar you can see it's going to give me different end points an endpoint is just the url so here we see if we want a list with all of the dog breeds this is the exact url we can use so if i copy and paste this url into a new tab aha it gives me a bunch of raw data but there you can see there's all the different dog breeds okay so we can use these values to populate our select drop down element and then not to get too far ahead of ourselves but once we have the breed that we're interested in here you can see from their dog app api documentation there's a by breed endpoint so if i click on that if you want to get all of the images for a specific dog breed this is an example of the url you can use right so it's their address slash api slash breed and then this is the part that you would hollow out and make dynamic so instead of hard-coding it to hound you can just put in any dog breed here right and then slash images and if you view this in a new tab that's going to give you all of the urls for all of the images for the hound breed so i think you can sort of see that with a bit of programming we can use the dog api data to build out our dog slideshow so at this point the first question becomes how in the world can we programmatically consume that data or how can we use our javascript to go out onto the internet right and this is the first one that we would want to fetch right it's just the url that lists all dog breeds how can we fetch or retrieve this data with our javascript well let me show you so first we would want to copy the address or url into our clipboard okay and then remember we just have this empty web page with hello world so back in vs code within our main js file we can get rid of this console log hello from our javascript so we have a clean slate and let's say fetch parentheses to call it this is a function that the web browser offers to us so we didn't have to create this function we're just calling it the idea is inside these parentheses we give it an argument so quotes we give it a string of text or url so i'm just going to paste in my clipboard so we're just saying we want to fetch whatever data lives at this url so this code looks simple enough but there's actually a bit of complexity going on because fetch is not just going to return the data that lives at this url instead the fetch function is going to return a promise so the question becomes what in the world is a promise well before we even get into promises let me show you something really quick so down here if we say two plus two and then on a new line ten plus ten a hundred divided by ten now most of the time in javascript when it sees a line of code it's going to finish and complete that operation before it moves on to the next one right so any computer made in the last 50 years is only going to take like less than a millisecond to calculate two plus two but it's going to finish that before it moves on to ten plus ten it's going to finish that before it moves on to this line so on and so forth now this behavior of completing one action before moving on to the next action this makes sense when each action is only going to take a millisecond or less however when it comes to fetching data out on the web well that could take a long time we don't know how slow or fast someone's network connection is we don't know how long it's going to take for this server to actually respond and so this could take a while and we don't want to block the execution of all of our other code on the page while this finishes so back to the question of well if fetch returns a promise what in the world is a promise well it's a way of letting this operation run in the background and we don't care how long it takes it could take a second or five seconds but it's not going to block any of our other code from running so javascript could begin this task and then it's going to let all of these other tasks finish and then maybe five seconds in the future when this actually completes then we can do something with it now there are several different ways to work with a promise but let me show you what we can do so let me get rid of this example code so we just have our fetch line and actually for the next minute or two i don't want you to type this out with me and follow along because first i'm going to show you the way that promises have always or traditionally worked but we'll see that the syntax is a bit messy and hard to read or make sense of so then after that i'll show you the more modern way and that's when i'll want you to follow along with me but i don't want to just jump right into the modern way because i do want you to see how promises work in their simplest or traditional form first okay so again you don't need to type this out for the next minute or two but fetch is going to return a promise so at the end of this line we're working with a promise so we can say dot then to call a method so a promise has a method named then and in these parentheses we can give it a function as an argument and it will wait to actually call or execute this function until this has completed we as the programmer have no idea how long this will take it could be 20 milliseconds or it could be 10 seconds okay we just know that then we'll call it at the appropriate time and what's cool is this isn't going to block any of our other lines of code below it so we just list this out javascript will continue running all of our other code down here and then once this actually completes the function here can run so in these parentheses i'll include an anonymous functions a function parentheses curly brackets again you don't need to type this out when this function gets called by then it's going to pass this as the response into the function so for a parameter i'll say response now inside the body of this function i will return response.json so this represents the dog api server's response and then we're calling a method of json meaning we just want to deal with the actual data that it sent now for the longest time this confused me because i thought that this would actually return that data however this actually returns another promise itself so this initial promise will complete as soon as we hear back from the server at all and we just have basic things like the headers but then this is another promise and it will actually complete when we have the body or the data of the request and we've parsed it as json so now if this function is just returning another promise right this returns a promise we can just chain on at the very end here another then and that will only run once this is actually completed okay so then inside these parentheses we can say function parenthesis curly brackets when then calls our function it's going to pass in the data so i'll say data for parameter and then inside the body of this function i can say console.log data now i am fully aware that none of this made any sense i'm sort of making fun of the old school promise syntax right this code is ugly it's difficult to read it doesn't make intuitive sense and having to chain along multiple dens like this this just doesn't look elegant however if i save this and refresh in the browser and check my console this is what the dog api server is sending back if we expand it there's a property called message and inside message aha there is the list of all of the different dog breeds personal favorite of mine is corgi anyways so this was the ugly or traditional syntax of working with promises there's nothing wrong with using this approach for a long time this is really all we had as web developers however now that we have a general idea of how a promise works right just this general idea of they take an unknown amount of time and then once it actually completes we want to do something just with that in mind now let's look at the modern approach of working with a promise i'm actually going to delete everything on the screen right now so i am going to copy the dog url into my clipboard because i do want that let me delete everything okay now in order to use the modern or easier syntax of working with promises we do need to be inside of an asynchronous function so in our first lesson with javascript we learned how to make a function right you just say function and then you give it a name we could name it anything but let's name our function start so function start parentheses curly brackets so this is a regular or traditional function and to turn it into an asynchronous function you just write async as a separate word right before function so now that this is an async function inside it we can use the modern way of working with promises now i'm well aware that the promise code i wrote just a moment or two ago didn't make any sense i do want this code to make sense so type this out with me if you need to pause the video to type out async function like this that's great but inside the function here's what we're going to do let's say const response right the response from the dog server equals and this is the new part we say await and then fetch we call fetch inside the parentheses we give it that dog server url the end point now the key here is a weight this is super interesting so now below this if we say two plus two four plus four ten plus ten even though fetch returns a promise because we included the word await here this is super important await is going to make it so javascript will not run these lines of code until this actually completes until the promise returns or resolves we can get rid of these math lines so now this is pretty cool now on a new line still within this function we can say const data equals and again we can use await and just say response.json okay and then below that on a new line we can just log that data to the console console.log data ultimately we don't really want to just log the data to the console eventually we will want to use the data to build out this html select drop-down but for now let's just log it to the console now in just a moment we can circle back and i'll explain what this code is really doing but for now this is just a function definition so in order to actually have this code run or execute we need to call our function so right below it let's just say start parentheses to call our function so if we save this and reload in the browser and check your console you should now indeed see this right this is the dog server's response and inside it there's a message property with all of the breeds let's talk a little bit about what's going on here so fetch is going to resolve its promise as soon as we hear back from the server at all so as soon as we just have really basic header information from the server this will resolve okay then we're taking that response and we just want the json data json stands for javascript object notation so this is where we want the actual body or the meat and potatoes of the response from the server and we want to parse it into a readable format right and we're storing that in a constant variable called data and then since we awaited that right we're awaiting until that is actually finished well now we can do anything we want with that data and we don't actually want to log it to the console we actually want to build that html select drop down so let's go ahead and do this let's get rid of this console log line and we could write out the code to transform the data into an html select right here however i like to stay organized i want each function to sort of be bite-sized or have just one single responsibility so let's say the responsibility of this function is just to get or fetch the data and then let's have the code that creates the html select let's have that in a different function so maybe down here the very bottom of our code let's create a new function and you could name it anything but i'll name it create breed list parentheses curry brackets and then in this function where we were logging it to the console let's just call this function and pass it our data so create breed list parentheses to call it and give it an argument of data and actually let's say data dot message because if you look in the console in the browser remember the server is giving us back this bit of javascript code with two properties message and status status just says success but the message property is really what contains the list of dog breeds so really that's all we're interested in passing on to our other functions so data.message now in this function let's receive this with a parameter so in these parentheses you could name your parameter anything you could call it x or pizza or unicorn why don't we call it breedlist okay now it's up to this function or i should say this function has one single responsibility of just taking that data and creating this sort of html select drop down so with that in mind let's dig into our html because right now our page just looks like this and let's give ourselves a bit of html that we can hook on to with javascript so back in our html first of all let's change the hello world to be a heading level one that says infinite dog app and then right below that let's create a div so div and then to give it an id with the tab trigger system you can say div hash tag and then the name of the id and then if you hit tab that gets converted into a div with that id okay now inside this div let's create that drop down or select element so it's just select hit tab we actually don't need the name or id on this opening tag and then inside the select you just include multiple options so option hit tab we actually don't need a value if you wanted the value to be something different than what you visually see that's what this is for so for example if you wanted someone to visually see three but you wanted the actual value to be the digit three you could do that we don't actually need the value though so let's just remove that and for example for the first one we can say choose a dog breed okay then below that just for an example let's hard code a few dog breeds so option let me get rid of that value let's say corgi copy and paste that a few times let's have boxer and bulldog let's go ahead and save that and then if we refresh in the browser cool infinite dog app choose a dog breed you get the idea now we don't actually want this to live in our html though we want our javascript to be able to create this so let's do this we want to keep our div with an id of breed but i want you to copy this entire select so just like this let's cut this entire thing into our clipboard because we want to be able to use it in our javascript so let's save this with just the empty breed div now then back in our javascript inside our create breed list function let's say document dot get element by id and that's a method give it an argument of quotes we gave that div an id of breed this will return an object that represents that empty div and then let's look inside it and set its inner html property to equal and now we could just say a string of text so simple quotes and then hey and then if we save that and refresh we do see hey right there however what if instead of just a simple bit of text we want to be able to have something that can drop down to multiple lines well in javascript a regular string of text or a quote cannot drop down to a new line however if we get rid of that and say equals and then two back ticks this is the character to the left of the one key or right above your tab key we want two of them and now in between them we can drop down so maybe in between them right about here i'll just paste in my clipboard right so now we have that select element let's save that refresh cool so now we have this element only now all we need to do we don't want these options here to be hard-coded we want to dynamically or programmatically loop through the breed list that we retrieved and display all of them here so let's actually keep this first one that says choose a dog breed but then let's get rid of these three hard-coded corgi boxer bulldog and instead within a template literal which is what we're in because of the two back ticks right so instead of just a traditional string of text we're in a template literal in here we can say dollar sign curly brackets and now inside these curly brackets we can do something dynamic now if you watched my 10 days of javascript playlist here on youtube you'll know that it's fairly easy to loop through an array using something called map however this list of breeds that the dog server gives back to us it's actually not an array it's an object with a bunch of properties but luckily for us javascript has a great way of returning an array based on an object's property names let me show you what i mean so in this dollar sign curly brackets let's say uppercase o object this is javascript's big picture blueprint or sort of cookie cutter mold for all objects and we can look inside it so dot for a method called keys now inside these parentheses we give it an object and then altogether this is going to return an array if you don't know what an array is that's okay but i do strongly encourage you to pause this video and in a new tab maybe go watch day number four of my 10 days of javascript anyways in these parentheses let's say breed list so this will return an array and in javascript all arrays have access to a method named map so after this closing parenthesis but before the closing curly brackets we can just say dot and then call map if you've never heard of map before that's okay we definitely have not covered arrays or map in this bootcamp series but again this is all covered in the 10 days of javascript anyways we just give map a function and it will run that function once for each item in this array or collection so let's provide an anonymous function here in map so function parentheses currently brackets now each time map calls our function it's going to pass into it the current item that's been looped to so in these parentheses we would receive that with a parameter we could call it anything but let's call it breed okay then inside the body of this function let's return another template literal so return back ticks let's say the html option element right we want one of these for each item in this collection inside the opening and closing tags we'd want to do something dynamic so dollar sign curly brackets inside there we just say breed okay now map is going to return a brand new array where each item in the array contains this but that array when converted to text because we're in a template literal is going to be separated by awkward commas we don't want that we just want one seamless string of text without any weird commas so right after this closing parentheses here where map is returning the new array we can just say dot join join converts an array into one single string of text and then we can just give it a value of nothing well not nothing but just an empty string with not even a space so there won't be any sort of separation in between the items okay let's go ahead and save this and i'm fully aware that i didn't explain map and join in order to really understand how this is working you will want to go watch the 10 days of javascript but for now let's not get too sidetracked on this let's go ahead and save and if we refresh you can see after refreshing it takes a few hundred milliseconds or however slower faster internet connection is but it went out onto the web not only did it fetch that data but then our javascript dynamically created all of these options cool so where do we go next from here well now when a user clicks on this and actually selects one so let's say they click on beagle well we want our javascript to respond to this event of this select changing its value and then we'd want to take whatever value they chose and we'd want to use that and then to think back to the dog api server we'd want to use the end point of by breed right instead of the end point that selects all dog breeds now we want to work or fetch data from this type of url so you'd hollow out instead of hound here it would be beagle or whatever the user selected but we just fetched the data from this and that would give us an array of all the images for that dog type but let's not get ahead of ourselves let's take this one step at a time so first we just want to respond to that event of this input changing its value so in our javascript when we're creating this select html on the opening select tag let's give it an attribute so right here we can just say on change all lower case on change equals quotes and our text editor doesn't know that we're in html right now it still thinks we're in javascript so when you say one quote it doesn't know to automatically add the second ending quote so just be aware of that we want opening in closing quotes and now let's just have it run a separate function remember i like the idea of each function being bite-sized or sort of having a single responsibility so our start function fetches the breed list this function is just responsible for creating the select element and then why don't we have a separate function so maybe down here let's create a brand new function and let's name it maybe load by breed parentheses curly brackets and then that's what we want to call in this on change equals quotes just say load by breed parentheses to call it okay and then in these parentheses we would want to pass into this function whatever value the user has currently selected right so beagle or could be any of these other ones so in these parentheses you can say this now the keyword of this is a huge topic in javascript we're not going to get into it here we do cover it a little bit in the 10 days of javascript but for now just know that this is sort of pointing towards the element in question or the element that triggered or that is calling this function so the select element itself and then we can just look inside it so this dot value now to test this out and to make sure you typed in everything correctly in our new load by breed function we'd want to receive that argument with a parameter so again you could say x or anything but let's say breed and then in the body of this function just for a test let's have an annoying alert pop-up that shows what breed you selected so just alert in the parentheses breed if we save that and then refresh in the browser so go ahead and select i'll choose beagle again and there is that annoying pop-up with beagle and now anytime we change that we're going to see the new breed so there's bulldog really quick though let's set up a bit of conditional logic so that if you change it back to choose a dog breed we don't actually acknowledge that because obviously on the dog server api there is no dog breed called choose a dog breed so here's what i would do inside our load by breed function i would just we can get rid of that alert say if parentheses curly brackets for the condition in these parentheses just say if breed does not equal so that's exclamation equal to check for the opposite of equality if it does not equal quotes choose a dog breed and you will need to type this in exactly the way you typed it in up here so capital choose so now code in here will only run if it's something other than this so here we could again say alert read give that a save refresh so now if i choose boxer cool that fired our event but if i change this back to choose a dog breed perfect nothing happens cool so from this point we now can access the value that the user chose we don't actually want to alert it though so let's get rid of that what we would actually want to do is use fetch once again to send a request to the dog server for that one particular breed so if we're going to use fetch that's going to return a promise and if we want to be able to use the await syntax with our promises we need this to be an asynchronous function so right at the start of this line we can just say a sync okay now inside our if statement we can just say const response equals a weight and then we just use fetch once again so fetch inside these parentheses let's go find that dog server url pattern so from the dog api website under documentation we're interested in this by breed okay then you can just copy and paste this url pattern here we can paste that in here now we don't actually want this to be hard-coded to hound though we want this to be whatever breed our user just selected so actually inside our fetch instead of quotes let's use back ticks so we can do something dynamic so now paste in your clipboard inside the back ticks let's hollow out or delete hound we want that part to be dynamic right so then dollar sign curly brackets and say breed cool on a new line of code let's say const data equals await response dot json parentheses to actually call that okay and then just as a quick test let's log the data to the console just so we can see visually sort of what the server is giving back to us so console.log data let's give that a save and test it out so back in our page if i refresh if i choose boxer and check my browser's console you can see it gives me an array with 153 items so that means there's 153 photos of boxer dogs and there you see them it looks like google chrome organizes them in groups of 100 but you can take any of these so take this first one for example this path or url copy that in a new tab cool you get the idea right that's a url for a box or dog so now at this point we have we go back to my console we have the exact data we need at this point the rest of this tutorial has nothing to do with fetching data from an api and it's just going to be sort of the user experience of building out the actual slideshow to show those images visually and then every two or three seconds or however many seconds you want switch to the next photo and then in another three seconds show the next one now actually before we write the javascript to make the photo switching happen let's first look at the finished product example and let's actually write a little bit of css to create this layout where this section takes up just the amount of space it needs and then the entirety of the remaining screen space can be the slideshow area right it doesn't matter how short or tall your browser window is the css makes it so this slideshow area will expand to fill your entire screen so let's set up this basic css skeleton so back on our page which looks quite boring at the moment in our html let's add css so in the head section maybe right after title we can just say link and then hit tab for the href value let's point towards a file named main.css let's save this now let's go create a file with that matching name so new file name it main dot css okay let's begin by selecting the body element which is the overall element in get rid of any margin and let's also say font family sans serif let's go refresh that now let's adjust the html to have maybe a couple of divs to handle this structure of sort of the header area and the slideshow area so back in our html let's actually get rid of all the content so far except for just the script tag i think it's easier if we just start fresh and i'm going to have an overall div with a class of app so div dot app hit tab inside that i'll have one div with a class of header and then below the header div i'll have one div with a class of slideshow okay inside the header div let's have our h1 that says infinite dog app then right below that in that same div let's have our div with an id so div tag breed hit tab okay and that's really all we need for the html so now if we save that nothing changes visually but now let's add a bit of css to create the separation between header and slideshow so in the css i will target the overall app div so dot app i'll tell it to have a height of 100 and i'm gonna spell out a width of 100 now any block level element will use the full available width without us spelling it out like this but because i'm going to use absolute positioning for the slides i do just want to spell it out here anyways on this same div let's also say display flex and by default flexbox is sharing the space horizontally right so multiple items can fit on the same row instead i want to switch the flex direction to be column so if we save that and refresh it doesn't seem like anything changed because that's how divs are aligned by default right one sits on top of the other vertically however because that parent div of app uses flexbox now we can tell the slideshow div to take up all of the remaining vertical space so to do that we can just target our slideshow div and tell it to have a flex value of one now visually it's hard to tell that it's taking up the full space because it's empty right the slideshow div is empty however if we give it a background color now that it's using flex one background color hashtag 333. now if we try cool you can see that it's using the full available remaining height okay really quick let's just center this content horizontally so in our css we can target our header and just say text align center maybe i'll target the h1 inside the header and just say for margin it shouldn't have any on the top right should have a little bit on the bottom it doesn't need any on the left to test that out okay maybe give the overall header element a bit of vertical padding so header let's say padding 20px and zero okay let's tell the select to maybe use a slightly larger font size or at least the standard font size this looks a little bit small so i would just say header space select font size one rem cool okay now in terms of how we actually display the images here there's many different ways we could set this up if you asked a hundred different developers to code a slideshow you would get a hundred different solutions this is just the way that i'm going to do it because there's nothing else on the page and we really don't need the slideshow to sort of fit into the content on the page i just want the slide to take up this full available space and i want the image to scale to fit inside this not just horizontally but also vertically so while we could add image elements in the html right the img tag i'm actually instead going to use css background images to display the image let me show you what i have in mind so back in our css i'm going to tell the slideshow to use position relative so that way i can position its children in relation to it using absolute positioning let me show you an example of what i have in mind for now let's actually just hard code this with html and then once it's up and running we can switch to javascript but inside the slideshow div let's add a new div and give it a class of just slide let's give that a save now back in our css let's target slide brackets and let's say position absolute and now i want it to take up the full available space so not just the width but even the full available height so i would say top 0 bottom zero left zero right zero [Applause] okay so now each slide is going to take up the full space to test this out you could say background color red save refresh you get the idea so each slide each dog photo is going to be a slide div and it will take up the full screen let's get rid of this background color line instead we're going to use a background image so we can actually save this and jump into your html because we want to be able to control the image from our html or javascript so on this div with the class of slide right after the quotes we can give it another attribute of style equals quotes and here you can include a bit of inline css so we're just going to say background dash image colon url parentheses pair of quotes and now let's just temporarily hard code a url to a dog image so i still have in my clipboard the url to that one box or dog photo okay let's go ahead and save that and refresh so there it is only we don't want it to tile and repeat right this looks very 1997. so instead we want to tell it to size the background image to fit within this entire area and we don't know if the image is going to be wider than it is tall or taller than it is wide we have no idea what sort of images the api is going to give us so what i'm going to do back in the css on that slide i'll just say background repeat no repeat so that'll stop the tiling and then i'm going to say background size contain just to make sure let's say background position center both horizontally and vertically okay let's go ahead and save this and test it out cool so the contained value is the star of the show here it's going to automatically size the image to be as large as possible while still fitting in our container i think this will work nicely but if you don't want to use contain you could also try a value of cover and that will fill up all of the available space but there's no guarantee that it's going to crop the image in a way that makes sense and because there's so many different image aspect ratios in this api i'm just going to stick with contain for the most part this doesn't matter this is supposed to be a javascript tutorial not a css tutorial okay at this point now that we have the basic layout set up let's get back to javascript and let's have it use the array of images and after every three seconds we want it to switch to the next image now again i really believe if you asked a hundred different developers you'd get a hundred different solutions on how to implement this this is just what i would do so let's jump back into our javascript down at the bottom within our load by breed function we don't actually want to just log the data to the console instead what we want to do is use javascript to add html into that empty slideshow div so for example back in index.html i want you to select this entire div with a class of slide and just cut it into your clipboard because we're going to want it in our javascript okay but we want our html to just have an empty div with a class of slideshow let's save that now back in our javascript remember we like to keep each function having just one responsibility so the job of this function is just to load the images for a breed so let's just pass this data off to a separate function so maybe at the very bottom in a totally separate function let's say function create slideshow parentheses curly brackets okay and then in this function after the console.log let's just pass it into that function so create slideshow and let's actually not just give it data but give it data dot message the reason for this is if you refresh your page and click on a dog type and check the console the javascript that the dog server sends back to us all of the interesting array of images live inside a property named message now we didn't make up this name of property of message this is just a name that the dog server chose to use but that is what contains the actual array of images so that's what we want to pass into our function okay we can get rid of this console.log up in this function in our new function let's receive that incoming argument with a parameter so we'll say images you could call it anything and then just for a test inside the function we can say console.log images give that a save refresh i'll choose corgi check the console awesome so instead of an object with different properties like message and success or failure we literally just get an array with a bunch of images okay now at this point again this function's only job is just to load the data now it's up to this function to actually create the html for that empty slideshow div so inside this function we don't actually need to log the data to the console what we really want to do is select that empty div so document and actually let's go give that div an id in our html just so we have an easy way to hook on to it in the html this empty div with a class of slideshow why don't we just also give it an id of slideshow okay be sure to save that back in our javascript we just say document.git element by id we're looking for the id of slideshow this will return an object that represents that element and then we just say dot inner html equals let's use back ticks so we can drop down to a new line and here let's just paste in our clipboard right so this was that html with the div that has a class of slide and then we're setting the background image now let's actually go ahead and make this dynamic so we don't want to hard code it to a specific image so i want you to select and delete from the beginning of https until the dot jpeg and in these quotes to do something dynamic in a template literal we just say dollar sign curly brackets inside the curly brackets we would just say images that's the array of images from the server and then in javascript after an array you can just say square brackets so that's the character to the right of the p key and to access the first item in the array instead of a one it's actually a zero arrays are zero based okay so this should give us the first image for whatever dog breed we choose let's test it out so if i save that and refresh let's go ahead and choose beagle awesome i like the vibe of this photo uh let's change it to corgi cool so that works now we just need to set up a timer that happens maybe every three seconds that switches to the second photo being displayed and then after that display the third photo so on and so forth now to achieve this we could just change the background image url so every three seconds we could change this from zero to one and then to two to three you get the idea i just change this every three seconds however i don't just wanna switch the image immediately instead i want an animation or a gradual fade between the two photos right if we look at the example of the finished product and i choose beagle notice when the image switches to the next image the old one sort of fades or zooms out and the new one sort of fades or zooms or animates in so to achieve this effect we're going to need to have more than one of those slide divs at once because if you think about it we want the old photo to still exist on the page for that split second while they're both sort of either fading out or fading in or transitioning between the two so let me show you what i'm going to do let me put this array index back to zero right to load the very first image and instead of just having this single div with a class of slide i'm actually just going to duplicate it so that there's two of them okay the first one can show the first image the second one instead of zero one right to show the second image so when you first load a breed of dog two images are going to be added to the page and then three seconds in the future we can add the third image right here so then there would be three total slide divs and we can just use css to write a selector that says the second to last slide div should be the one that's visible so then every three seconds we add the new photo to the end of our collection and we just remove the oldest photo right and css will sort of handle animating or fading or zooming or transitioning between which one should actually be shown let me show you what i mean in the css so right below this rule for slide let's have a new rule and say dot slide colon nth dash last child parentheses with a value of 2 so that will select the second to last item of this type and let's say opacity 1 to be fully visible let's set the baseline style to be opacity zero so that it's invisible and then to create that nice zoom effect down here be sure to add a semicolon let's say transform scale maybe 1.08 and then on the baseline style we can say transform scale just one the regular size okay then on this baseline style we just tell it to transition gradually so we say transition all properties over the course of 0.9 seconds and use the ease out timing function let's go ahead and save this so now in javascript as we add new images onto the end and we remove the oldest or first image this css selector will take care of always making sure that the second to last image is the one that's actually visible so now back in our javascript let's first create a variable that keeps track of which number we should be on right and then we can increment it once every three seconds to control the next image that should be shown so maybe towards the top of our create slideshow function maybe right above this document line i'll say let's position i just made up this variable name but let that equal zero okay and then after we display the initial two slides so right after this template literal so right after this closing back tick right below that i can just say current position and we just want to add on 2 to it so plus equal 2 right because we've already used the zero image and the one image so we'd want to advance our counter to images that have already been displayed and now this is where we would want to set up a timer so beyond this now every three seconds from now we would want to advance this one more let me show you what i mean so right here we can say set interval this is a function that exists in javascript and you give it two arguments so the first is a function that you want to run we haven't created this function yet but we can create it in just a moment why don't we call it next slide okay comma the second argument is how many milliseconds you want to wait before running this so let's say 3000 milliseconds so it waits this long before running it the first time and then subsequently it's going to run it every 3000 milliseconds after okay now we better go create a function with this exact matching name so right below this we can just say function next slide parentheses curly brackets and notice where i created this new function so we're still inside our overall create slideshow function so yes you can have a function inside a function we're doing this so that within next slide we have access to the current position variable this has to do with the topic of variable scope which we're not going to get into here but we do cover it in the 10 days of javascript so in this function the first thing i want to do is just add on another slide div at the end of this html so i would just grab one of these slide divs into my clipboard then back in next slide let's start working with this slideshow div so document dot get element by id quotes slideshow and we don't want to set its entire inner html instead we just want to modify what's already there we want to add on to the end of it so we can say dot insert adjacent html and we give this two arguments the first will say before end so before the end of this element is where we want to insert this new html comma the second argument is just the html that you want to add so i'll say two back ticks paste in my clipboard okay and now in terms of which image from the array we want to show let's get rid of a number here instead we would just want this to be current position okay now we would also want to remove the oldest photo from this html after it's had a chance to sort of animate or transition out of view now remember in our css we said that the transition should take point nine seconds to fully animate so why don't we just wait one second before removing the oldest photo from the html so within our next slide function right below this first line that we just wrote here's what i would do we can use a function in javascript called set timeout this is really similar to set interval you give it two things a function and how long you want to wait only timeout isn't going to keep running it again and again it's just going to run it once after a delay so if we give it two arguments a comma b the b would be 1000 milliseconds we want to wait after we wait that long we just want to select and delete the oldest slide div so you could create a different named function and point towards it or we could just use an anonymous function here so function parentheses curly brackets inside this function we just want to remove the first element that has a class of slide so i just say document dot query selector and then you can give this a css like selector so just dot slide and this will not select all of them it just selects the very first instance of this so it'll find the first slide and then we can just say dot remove okay now below this set timeout block of code so right after the thousand closing parenthesis let's also say that after this runs we want to increase current position by one so that when this runs again in 3000 milliseconds well this would now point towards the fourth image and then the fifth and sixth and seventh image right we need to advance the current position but what happens when we get to the end of the collection of images so what if there's a breed of dogs and it only has maybe five images well once we've shown the fifth and final image we would want to circle back to the zero or the first image so i would just use an if statement so if parentheses curly brackets right after those i would also say else curly brackets for the condition i would just say if current position plus one is greater than or equal to images.length so this is our array of images every array in javascript has a property of length that is a count of how many items it contains so if the current position plus one is greater than or equal to that we want to set the current position back down to zero so we can start over in the slideshow so current position should equal zero else otherwise we would just want to increment it by one so current position now you could say equals current position plus one or you can just say plus plus right after it to increment it okay let's go ahead and save this and test it out so if i refresh let me choose corgi okay so it's working but notice there's the weird horizontal scroll bar and the image is a little bit taller than the container this is because i added the zoom effect you can see it sort of looks like the photos are zooming in and out we would just want to tell the container to have overflow hidden to fix that so back in our css let's find our overall slideshow div i would just say overflow hidden test that out again i'll choose boxer cool now one detail i want to take care of is if you're already viewing the slideshow for one breed but then you switch to a different breed well i would want to delete or cancel the timer that's going to run every three seconds for the old slideshow so let me show you how we can do that back in our javascript up at the very top sort of in the global scope of our entire file let's create a variable and call it timer and why don't we also create one call it delete first photo delay they don't even need to equal anything we're just establishing variables with these names in the global scope okay then down in our create slideshow function right here when we're setting current position to equal zero this is where when we're loading a new slideshow right this is going to run anytime you choose a new dog breed this is where we can just cancel the existing timeouts and the existing interval so we can just say clear interval and then you just give it the name so timer and then clear time out give the name was delete first photo delay okay and then down below when we're actually setting the interval in the timeout we would just want to set them to equal that variable so when we say set interval at the start of this line you just say timer equals set interval right so now it's going to be working with this thing that we can clear this variable that we have access to later and then let's also find the set timeout so right here at the start of this set time outline we would say delete first photo delay equals set timeout let's give that a save so now if i refresh and if i load corgi and then if on the fly i switch to boxer cool everything continues to work as expected before we're done though we do need to take care of a few edge cases so what if a collection of dogs only has one image or only two images we would want to adjust our logic a bit so for example the dog breed of finish in this api only has one photo so in that case here's what i would do so this line where we initially add the first two images let's add a bit of space right above that from that line down to where we set the timer i'm actually going to cut that into my clipboard and set up an if-else block so if parentheses currently brackets else curly brackets for the condition i'll say only if images.length is greater than one so if that's the case then in the if block you can just paste your clipboard back in but otherwise else if there's only one image well i just copied this line of code so from document down to the ending backtick in the else block paste that in we don't actually want to display the second photo so just get rid of style we do want to keep just an empty div though so that our css continues to make sense because our css says that the second to last div of slides should be shown so if we just have an empty div here this will still work okay the idea is in this else block we're not calling set next slide every three thousand milliseconds if there's only one image in the entire collection just do this and then don't do anything else okay and then finally what if a collection of images has only exactly two images right so if you think of the array that contains only two items in it there'd be the zero or first item one would be the second item and that's all that's in the entire array so we wouldn't want to set current position to two instead we would just want to set current position back down to zero so that it can loop through the images just the two images endlessly so to do that maybe right after this line where we say current position plus equals two i would just say if parentheses for the condition if images dot length double equal sign to check for equality instead of assigning equality so we're checking for equality if it equals 2 then you don't need curly brackets after the if condition if it fits on a single line right after it so we can just say if that then current position set it back down to zero okay let's go ahead and save this now we can test out these edge cases if we refresh i know that the finished dog breed only has one photo exactly so if i pick finish hopefully it just sits there and doesn't try to advance to the next photo it's looking good also i know that the dalmatian breed has only exactly two photos so if i choose dalmatian there's the first photo there's the second hopefully it loops back to the first perfect at this point our basic slideshow is complete before we bring this video to a close though i do want to show you one detail and that is how to deal with failure if your fetch commands don't work i should have shown this to you way back when we were actually working with the fetch requests but it's better late than never so back in our javascript let's take our start function up at the very top for example so imagine that someone's network connection goes down or for some reason the dog server api goes down we wouldn't want our javascript to run into a huge error and everything to just break instead we would want things to sort of fail gracefully so here's what i would do everything in this function right these three lines of code in the body of the function let's just copy those into our clipboard and instead we can set up a try block so try curly brackets right after that catch curly brackets and actually to make older versions of microsoft edge happy right after catch we do want to say parentheses e i'll explain what this is in just a moment in newer browsers this is optional but in older browsers you do want to include this anyways in the try block you can include whatever you want to try and then if it fails if it runs into any sort of problem or error then the catch block will run and the catch block only runs if there's a problem so in the try block we could just paste our code back in in the catch block we can say console.log there was a problem fetching the breed list now to circle back to this e or error parameter this contains information on the exact error that happened in certain situations that's going to be super useful in this situation i don't think the visitor of our website really cares what the technical reason was so we're not actually using it we're just going to display our own custom message now if we save this and test it out we won't see anything in the console because we're not running into an error however if your internet went down or the dog server went down or there was any sort of problem in our code so for example right above this line if we just say just gibberish so there is no variable to reference with this name so if we hit save that's going to create a problem javascript knows if there's a problem in the try block the catch block should then be executed so there was a problem fetching the breed list so you don't need to do this in every situation right because if you're just saying two plus two that has zero chance of failing so you don't need to wrap that in a try catch block this is really just for situations that could likely fail okay cool let's test it out one more time boxer looking good that is going to bring the technical aspect of this video to a close that was a long video now i don't think it's realistic for me to expect that you just absorbed 100 of that material however hopefully this video inspired you or gave you a few ideas of other apps that you can create so for example at the very start of this video remember that github page called public apis maybe now you want to go back and revisit that page find a different api to work with instead of just the dog api and build your own little sample application that pulls in the data the possibilities are infinite and i think it'll be a great exercise for you to maybe try to put something together on your own anyways looking ahead to the next video we're going to build a simple math game so it'll ask you simple math problems and then if you put in the right answer if you get 10 points you win if you get three wrong answers you lose so that's what's coming up next and if you've been enjoying this series so far as always i'd appreciate it if you share the link your friends and family take care and i'll see you in the next [Music] video you
Info
Channel: LearnWebCode
Views: 37,945
Rating: 4.9803648 out of 5
Keywords:
Id: AVmGmLFcukM
Channel Id: undefined
Length: 69min 16sec (4156 seconds)
Published: Thu Sep 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.