‫So let's now talk about the problems
‫that can arise when we use too many call back functions.
‫And to do that,
‫we're gonna do a small example
‫to illustrate this effect.
‫Now remember that if you're already familiar with
‫Promises and Async/Await and in general,
‫Asynchronous Java Script,
‫please feel free to just skip this section
‫and mark all the videos as completed
‫so that you can still get to 100 percent completion
‫of the course.
‫But if you want to learn all about
‫Asynchronous Java Script
‫and how to use it in OJS then let's move on.
‫So go ahead
‫and get the starter files for this project
‫from the course files.
‫I already have it here on my desktop,
‫so this folder here.
‫And it's only this file in there,
‫so that's all we're gonna need to get started.
‫And I have it here in VS Code already opened
‫and what we're gonna do to start
‫is to just create an NX.JS file.
‫Just like before.
‫Now what we're gonna do is this,
‫we're going to use this,
‫this dog file here, this text file.
‫And from here we will read the dog breed.
‫And then we are gonna do an HTTP request
‫to get a random image of a dog with this breed.
‫And then save that random image
‫to another text file.
‫So it's a three step process
‫and all of this will involve call back functions.
‫And by the end we will see the problem that we have
‫when we use all these call back functions
‫inside of one another.
‫Okay?
‫So for that we're gonna use a
‫quite a popular API.
‫Which is more like a fun API.
‫But for this kind of stuff
‫it's a good idea to use it.
‫So it's the DOG.CEO, API.
‫So just hit Dog API here.
‫Then over here,
‫the documentation.
‫And what we want is to get a random dog,
‫or a certain breed.
‫So click by breed here.
‫And down here,
‫down here is the API endpoint that we're gonna hit.
‫So it's this URL here.
‫So when you click on fetch here,
‫each time you get a new image, okay?
‫And so in this section
‫we're actually gonna do HTTP request
‫just like we learned about before
‫in the previous section.
‫Okay.
‫So all we will have to do
‫is to create an HTTP request to this URL
‫and then it will get us back an image.
‫Okay?
‫But for now, let's actually start with a part
‫where we read the file and get the content
‫of that file.
‫So in our index.js, again we need the file system package
‫or module.
‫So FS
‫and require the FS module here.
‫And just like before we do fs.readfile
‫and we do the asynchronous version.
‫Okay.
‫Remember that in here we pass the location of the file
‫and then a call back function
‫which will be called as soon as we're done reading the file.
‫So we have our template string here.
‫And then we use a dirname just like we did before.
‫So the name of the current directory.
‫/dog.txt.
‫Okay and then our call back function
‫which the first argument as always is error.
‫And then the data that actually is in the file.
‫And just to make sure, let's log it
‫to the console of course.
‫So another template string
‫so that we can nicely output our data here.
‫Okay.
‫Start up the terminal here
‫and
‫bring it up a little bit.
‫And so I'm using nodemon just like I did before
‫and then index.js.
‫Okay so breed is retriever.
‫And that is exactly what we have here in this file.
‫Okay so retriever is the breed that we will be looking for.
‫Now inside this call back function,
‫we want to do that HTTP request
‫that we just talked about before.
‫And there's actually ways of doing it
‫with native
‫no JS modules.
‫But it's easier to just use an NPM package for that.
‫And there are many again,
‫but the one we're gonna use is called Super Agent.
‫Later on we're gonna use another one
‫but for now Super Agent is just fine for that, okay.
‫And in order to actually download this module using NPM,
‫we're gonna start by creating our packet Jason file.
‫Remember that?
‫So let me just finish this
‫and do NPM in it.
‫And just hit enter on all of these.
‫This doesn't really matter.
‫Okay.
‫We just want this package .jason file
‫so that it actually holds the name of the package
‫that we're using.
‫So we always do that whenever we start a new project.
‫And now NPM install,
‫or we can just use the I, which is the same and then
‫the name of the package.
‫So nothing new there right?
‫Now to use this package,
‫we create a new variable
‫which will then contain the Super Agent function
‫that this module exposes to us.
‫Let's now go ahead and actually use that Super Agent
‫function.
‫So for doing a get request,
‫we simply used to get method on it.
‫So get and then we need that URL.
‫Okay so this one that I showed you before.
‫So just copy it
‫and paste it here
‫into a template string.
‫Because now we are actually going to replace
‫this breed here.
‫Okay, so we don't want that
‫but instead we want to use it,
‫the one that we get from our file.
‫So in this case it's data.
‫Right?
‫And so like this,
‫we can actually do an HTTP get request.
‫Now to then get the data,
‫we actually will also have to use the end method on this.
‫And this is then where we're gonna pass in
‫the call back function.
‫So again it's an error first call back
‫and then
‫we pass in the result as well.
‫And so in this function,
‫let's first of all
‫log the result to the console.
‫So the data that we get is in the response variable.
‫So this one here.
‫And then on that is the body.
‫So that's where the actual response is.
‫Okay, now let's actually go ahead and test that.
‫And now with this save here it actually moved down.
‫So again that's because
‫of the previous extension that we set up earlier.
‫And maybe you also noticed
‫how it replaced the normal quotes that I had here
‫with these double quotes
‫and also it inserted the semi colon up here.
‫And actually in the last section,
‫or in one of the last sections,
‫we set it up so that we always have
‫the single quotes okay.
‫And so in order to keep our code consistent here,
‫let's actually go ahead and
‫very quickly create the prettier config file.
‫So remember that's prettierrc.
‫Then in there we have single quote.
‫Set it to true.
‫And also remember the print width.
‫And set it to 80.
‫Okay, give it a save.
‫Save this one again.
‫And so you see we have our single quotes now back.
‫So that looks a lot nicer in my opinion.
‫Again if you don't like it this way,
‫you can of course use your own settings.
‫All right.
‫Anyway,
‫this piece of code here should now already
‫be doing the HTTP request.
‫So let's actually just
‫test it out.
‫And indeed,
‫we actually have this image here.
‫So actually what we want
‫is inside of this buddy
‫in the message property.
‫So dot
‫message.
‫So just like this.
‫And so here we have our retriever image.
‫Let's go ahead and actually change the breed here.
‫And I'm not really good with dogs.
‫Let's just use this breed here that I know,
‫Labrador.
‫I don't even know how to say it.
‫But I think it is it,
‫it exists.
‫Let's give it a save here again.
‫And so now we have another image.
‫We can actually click this here
‫and it will open that image for us.
‫Okay.
‫So for doing this HTTP request here,
‫we needed the data that we got before.
‫So this piece of data.
‫And so we needed to do this request here
‫inside of this call back function
‫of the read file function, right?
‫And so you already have a call back function here.
‫So this one inside a call back.
‫But now we will actually add another one.
‫Because now we want to save this string here
‫into a new text file.
‫And so we will do that here.
‫And then that again will have yet another
‫call back function.
‫Okay, make sense?
‫So fs
‫writefile
‫and then the name of the file.
‫Let's call that one dog image.text.
‫Then the data we want to save to that file
‫which is rest.body.message.
‫And then the call back function.
‫And this one won't have any data of course,
‫but we have the error again.
‫Let's log something to the console
‫like random
‫dog image saved to file.
‫Give it a save, it will then rerun
‫and here is our image file.
‫And actually you can see that VS code
‫displays that image here for us.
‫Give it another save here,
‫it will then rerun our code
‫and now we have,
‫indeed we have a different image.
‫All right.
‫So our code is actually working.
‫Let's just add a small error handle here
‫in case something goes wrong.
‫For example, let's say we add some weird name in here.
‫Run this again.
‫And so right now it's not gonna be able to find an image
‫for that.
‫And that will actually result in an error here.
‫So,
‫we should always do this kind of error handling
‫in the beginning and say
‫so if there was an error,
‫and we can just log error
‫.message.
‫And actually we should also say that we want to return
‫right away from this function if there's an error.
‫So it will return and
‫log to the console, this error.
‫And nothing else will happen then.
‫Okay.
‫So it says again, not found here.
‫And it didn't save anything to the file
‫because we already returned from the function up here.
‫Okay?
‫And the same actually down here
‫in case there is an error saving the file to disk.
‫Let's go back here,
‫give it another save.
‫And so now it's working just fine again.
‫Okay.
‫So this is just
‫a small example to show you how easy it is
‫to end up with call backs inside of call backs
‫inside of call backs.
‫And that's of course because,
‫we already know that in Note JS,
‫we should always use asynchronous code, right?
‫We did end up using call backs inside of call backs
‫inside of call backs.
‫And sometimes it can go even deeper of course
‫than what we have here.
‫You could of course have like 10 levels
‫inside of each other.
‫Now all these call backs,
‫they make our code look a bit messy.
‫It makes it difficult to understand
‫and also in general, hard to maintain.
‫Again maybe not at this level
‫with just three call backs inside of each other.
‫But if we had it even deeper nested,
‫it could quickly become a nightmare
‫to maintain code like this.
‫And that's why this pattern has been called
‫call back hell.
‫It's easy to identify this triangular shape
‫in our code.
‫It's what we have here.
‫Like this sort of triangular shape.
‫Whenever you see this,
‫it's a sign that you're
‫basically in call back hell.
‫Okay?
‫And you will maybe see or hear this term
‫when you do some Note JS research
‫or something like this.
‫But right now, this is actually the only way
‫that we know of,
‫of how to write asynchronous code at this point.
‫But we're gonna save that throughout
‫the rest of this small section.
‫So we're gonna learn how to use
‫something called Promises.
‫And that will then in the end
‫solve our problem and make our code easier to read
‫and to maintain.
‫So let's go do that in the rest of the section.