‫Let's now actually start to learn
‫how to solve callback hell by using promises.
‫And we're gonna start off by using a promise
‫for the agent appear request
‫instead of the callback.
‫And this is gonna work because the super agent library
‫actually has support for promises out of the box,
‫and so we can simply use them here.
‫For node functions, coming from internal node packages
‫like Read File, we will actually have to build the promise
‫ourselves, and we will do that later in the next lecture,
‫or so.
‫But for now,
‫I want you to learn how to consume promises
‫and only later how to build them.
‫Okay, so again we're going to start
‫with the super agent library
‫and more specifically with the get method here.
‫Because this method here actually returns a promise.
‫So without going into too much detail, for now,
‫a promise basically implements
‫the concept of a future value.
‫So basically, a value that we are expecting to receive
‫some time in the future,
‫so it's a bit like us saying, "Hey, server,"
‫or "Hey, API, please get me a random dog image
‫"in the background and let me know when you're ready
‫"and then give me that data back."
‫Okay?
‫So that random image is the value that we expect
‫sometime in the future.
‫And that is exactly the kind of request
‫that we're doing using a super agent library
‫in this example.
‫Right.
‫And the get method that we use again will automatically
‫and immediately return a promise as soon as we start
‫the request.
‫So the promise doesn't have a value yet,
‫because the server is actually still getting the data
‫from the server asynchronously in the background
‫but the promise is immediately available
‫and basically promising us that it will get some data back
‫in the future.
‫Okay, does that make sense?
‫And that state of the promise in that case,
‫so right in the beginning, is a pending promise.
‫So it's still pending, it still hasn't gotten back
‫with any data, okay?
‫So here at this point, we already have a promise
‫that we can work with.
‫Now all we need to do is consume it,
‫which basically means that we wait for it to come back
‫with the data.
‫And to do that, we use the then method on it.
‫So, all we do is to use then
‫and then in here, we pass a callback function.
‫This callback function will then be called as soon
‫as the promise is done doing its work and has come back
‫with the data.
‫And that data is then available as an argument
‫to that callback.
‫Now I like to call that the result.
‫And so, again in that callback function that we have here
‫we then have that data available.
‫So let's take all of this here and put it into
‫this then callback function
‫and actually get rid of this.
‫So we no longer need that,
‫and give it a save.
‫Now you might be thinking, well, we're still using
‫callbacks here, and yeah, that's actually true.
‫So this does not look like a big change for now,
‫but after we transform the whole example here to
‫promises, you will see
‫the big impact that promises will have on our code.
‫So that's basically if we have multiple promises,
‫we will be able to chain these callbacks onto one other
‫instead of nesting them.
‫Which is already a huge improvement.
‫Now one thing that I forgot to mention earlier
‫is that a promise as soon as it comes back with the data
‫is called a resolved promise.
‫So in the beginning it's a pending promise and
‫when it successfully gets the data,
‫it is then a resolved promise.
‫However, a resolved promise might not always be
‫successful because there might have been an error.
‫So we say that a resolved promise can either be fulfilled
‫or rejected.
‫The fulfilled promise actually has a result that we want
‫to use.
‫While a rejected promise is when there was an error.
‫So remember the situation that we had before
‫where we had a wrong dog breed.
‫So in that case, we had an error,
‫and we handled that error using this piece of code here.
‫Okay.
‫Now the thing with this then method here is that it
‫actually only handles fulfilled promises but it doesn't do
‫anything if there was an error,
‫because for that, we actually have another method.
‫So another mechanism of handling that.
‫And that is the catch method.
‫So right after the then method, we can chain
‫another method which is called catch.
‫Okay.
‫And so this one will get called if there was an error.
‫So in here, we actually have access to that error object.
‫And so let's now go ahead,
‫take this piece of code,
‫and put it here,
‫and now we can get rid of this.
‫Because actually in this then method,
‫we have no information if there was an error
‫or not because it only ever gets called
‫in case the promise was successful.
‫So if it's a fulfilled promise.
‫Okay, so this is kind of nice to actually separate
‫these two cases automatically for us.
‫So instead of having that weird handling
‫that we had before,
‫we can simply write all the logic for the successful case
‫which is the most usual one
‫because we usually expect everything to work all right,
‫but in case there was an error, we can input
‫some other logic down here into this error handler here.
‫So we keep that nicely separated.
‫Let's change it here again.
‫Give this one another save to run it again.
‫And so here we have Not Found,
‫and so you see that actually it did enter this catch
‫method here and didn't do any of the things
‫that's in this then method.
‫Now go ahead and fix this here,
‫close it,
‫give this one a save,
‫and here we go.
‫So that is how we consume promises.
‫So we started with this method here which
‫returned a promise and so on that,
‫we can chain the then method
‫which handles basically the successful case,
‫and then in the end, we also chain the catch method
‫which handles the unsuccessful, so the rejected, promise.
‫But as I said before, this kind of still looks like
‫it did before.
‫Right?
‫So we still have this callback function up here
‫so all of this callback function
‫and also here inside our then method, we have this callback
‫function of the writeFile.
‫So let's go ahead and fix that right in the next video.