How to Build an Ionic HTTP Loading Interceptor & Retry Logic

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone what's up this is Simon back with a new tutorial this time a bit more advanced topic using rxjs to create something to intercept our HTTP calls because if you implement an F especially perhaps in the enterprise context you will have a lot of HTTP calls like 40 50 hundreds and you can always implement the alert logic or the retry logic for just every call in there so it makes sense to have HTTP interceptors that basically intercept every call and perform something in the background so you can focus on writing the app making the calls and you're always sure that they're handled correctly so that's what we're going to do to date I've created already an ionic application to get started and I just made a few changes so I added the HTTP client module to our app module and I implemented a fake HTTP service that makes a few requests to a back-end that I will show you as well in a second so these are just standard HTTP calls we will see what's behind all of these different routes and then within the home page I just injected our servers and again implemented the functionalities to call the service and in some cases show a toast but that's really not the core part or the idea of this tutorial so therefore I just created this up front and again just a handful of buttons so right now these buttons some of them will deliver a result as we can see in the lock and we also see a toast but a lot of them will simply fail and if you have these calls in your patient you would have to write an alert controller and show the alert for all of these failed requests some of them would actually work so this one always returns something in on the third call so just a little something here and this final one is just an unauthorized call without an token so all of this is using a simple nest Jia's api i've this on Heroku if you're using or if you are a member of the earning academy you can also access this one it's in the code link below this video so basically the first call will just return some data the second call will return failure always the third one will as I said only returned data on the third call so very stupid logic in here but that's just for our demonstration and finally another one that shows a bit how a total refresh logic could work so if you supply a token in the query parameter you will get data and otherwise you will get an unauthorized warning so we can implement something in our app to handle this unauthorized for or one message and finally this one will just give us a totem back as an idea of an endpoint so here we go we got the home page and we can actually leave most of these places and focus only on one thing and that's creating an HTTP interceptor so I will create a new folder interceptors perhaps you have multiple interceptors in your application that can definitely happen as well and in here we will create a new file let's call this one HTTP loading intercept or TS right now you can't add this with the angular CLI I saw get up issue they said the community should create some schematics around this so we will just for now create this one manually so therefore we have to type our own injector but that's not a big problem so export class and let's call this HTTP request interceptor and this one implements the HTTP interceptor that's the basic idea around here yeah I'm not yet implemented that interface but that's not a problem so we got a constructor that we will also need in or at a later point and then the important function that you have to implement is intercept and we want to intercept on the request which is an HTTP request of the type any so that's just the standard model for the Interceptor and next HTTP handler so now we get everything in place and this one should actually return and observable off the type HTTP event and again any so let's see if I can close the brackets in the right order yes please import this yeah of course I'm not yet returning anything so in order to make this work I could simply return empty and then the handler would be fine to use our HTTP interceptor we have to open our app module and go to the providers array and in here just like we using a custom route strategy in here from ionic we can now provide for the HTTP interceptors there we go importing from the same package like module our very own class that is the HTTP request interceptor and call multi true so now for every HTTP request that happens in our application our own interceptor will be called and we can do whatever we want I think you already see the the possibilities that an interceptor brings one thing we're not really talking about in here is implementing your own JSON web token flow so there are packages for this as well but you could also easily do this yourself simply whenever an HTTP request comes in right here you intercepted you grab the JSON web token from the storage or you save it somewhere in the service if you already got it and then simply attach the token to the request and then let the request happen so that's really the core of an interceptor but now we want to focus on what happens if the request fails how we can retry it and also how we could implement a token reflash refresh flow so first of all in our intercept we're gonna use a loading to show a loading because that's also something you always have to implement in all these places and it's really a task that you don't want to do all the time so let's inject the loading controller and then we can or we could show the loading immediately that I will be a bit careful here so I will first of all get the top and if we already have a loading so has already a loading in that case we don't need to show it if we don't have a loading yet we can go ahead and create the loading let me bring in this snippet quickly so simply creating new loading control or whatever spinner or options you want to have and presented alright so that's the first step of course in the end we should also make sure that we dismiss it but for now let's continue in order to process the HTTP request we gonna return our next function so if you call next handle it will basically return and observable again and that's what the Interceptor expects so in here handling our own request we can add a pipe lock and do all kinds of operations on our observable so first of all let's go ahead with retry when can I get some code completion today no why why should I I'm actually in the same project and deleted code and I still don't get the code completion I am I really don't know why this happens all the time so import retry when from our exchange operators hopefully you will find the other imports my friend ok retry when expects to or fact that we return and observable again and also defines what happens even error occurs so what we're going to do is when we encounter an error let's say usually we want to retry it about three times automatically in the background would a little delay because you don't want to fire of three requests immediately if it goes wrong for a reason then we could also intercept that but let's just assume in general we wanted to do it three times the problem is that if we use something with a delay so that was the first idea I had in general here to return the error that pipe and then have a little delay of about a second and then just call take three if you do it like this the request would be called three times again but in the end if there's still an error you wouldn't catch that error perhaps we can try it like that but I don't have the code anymore open so can we perhaps do a little tap in here and lock it out so retry that might work as well let's see let's try our get retry fail because that one is the most interesting here so perhaps we see one request failed then we got a retry we do it again and now it works and now I'm completely out of sync because I messed up with my numbers so let me restart my API to to get this fixed again okay so what we see is the request was actually retried two times and then it was a success if my server is hopefully back up in a second I can do it in the regular way again let's do it we can just do the request that fails all the time so if you do the request that fails all the time we will retry it for about three times now as you can see with a little delay so there we got the three requests and in the end we don't really get any arrow back we can't really handle this anymore so that is really a problem of this approach and therefore I came back to stick overflow answer their phone and the idea in general is to basically handle your own retry count in here in the retry when so we can first of all get rid of this and then return our pipe lock and now manually handle this so just like before we're doing a delay of one second before we retry the call then we will tap into the result or tap into whatever we got at that point simply to show a little retry toast because I think a lot of this happens in the background and to show this I came up with a little retry count toast I would say so make sure that you also import the toast controller now try the toast controller and then for every retry that happens we will show our retry toast and of course that's not all because we also want to map our result so you can map the data you've perhaps used this in the past to extract values from a JSON response but in here we want to check if the entries know retries little typo in my brain I think if we increase the retries and it's already three then we want to handle it differently normally we will just return the arrow once again so this means another arrow happens and we're gonna retry it again that if we hit the end and still gonna error we're gonna actually throw the arrow and the difference here is that this will allow us to add to our pipe lock another catch Arab lock that will be triggered so that is a big difference right here I can actually comment this out so we can see it in the arrow keys we want to also now present an alert again let's do a little helper function with an alert control I getting a message nothing fancy but you just have to implement this in this one place and get alerts for every HTTP request happening in your application so private alert controller alert controller and then maybe we also want to lock this error and then call our present failed alert passing the error message I actually made sure that it's included as a message in the error response so of course this depends on your API implementation now what happens is that catch error also should return and observable so in that case we can fall back to empty which is basically an empty observable then completes our stream of events now let's try again and I said get failed will always return an error and now we will call it three times again retry one retry - okay we're not really counting correctly but then in the end you see that this happens on and on and I think yeah simply because we have no check in here and we're not increasing retries very good Simon commenting this one out let's also a way to handle errors just do an infinite loop of retries but I wouldn't recommend this so retry one of two two of three oh sweet Jesus 3 or 3 and then 4 of 3 we're not ending this retrial so if we now it our if statement with the throw error once we hit entries three you will see the difference we're doing it again we're doing at one time we're doing it two times we're perhaps also doing it three times and then we see error we seen alert but we're right now not dismissing all OD to implement this we can simply expand our pipe locks so you can really change everything you get in here and we can use finalize which will be called once the observable is finished so in here we can dismiss our alert controller and I will grab the logic from here once again just to make sure that there is actually a loading and then call this the loading controller dismiss so basically the same checking if we have loading in place and then this missing is so now we can retry it for three times we can still pass the error in the end if it still occurs to our catch arab block and within that block now dismiss the loading so retry it three oops you fail the text I got back from the API and then we're good now what happens if actually the retry succeeds is that we also do the retry just like we did before retry and then retrying again but finally success on third call again the finalized block is called for ending it and we can dismiss our loading and the data is passed through to our page so now we already have a quite powerful retry mechanism in place which means we will retry how often we want you can of course change this you could change the delay as well but now let's say you make a request somewhere and you get back a 401 meaning your unauthorized your totin perhaps expired in that case you want to immediately catch this error so I will add another catch error actually before our retry logic and within that catch era block I will mute this within that catch era block we will now check if the error error arm is an instance of instance of HTTP error response and if that's the case we want to switch this so I will just implement this for a one specific case and let me bring this in before I make any typos that I will regret and let's kind of just yeah the problem is that once you add a block like this it expects an observable and marks everything else as a read so if for whatever reason first if fails we can return throw error with the actual error that should mute already the highlighting and now we can switch our little status in here in case it's a four or one we can handle it and in the other case we will just default back to the same behavior like here so in the four or one case it just means our token is expired so let's add a new function in which we make another call to get perhaps in Utah and then assign that toe to the previous request so even if the user was unauthorized we can do this in the background without the user actually noticing that we refresh the token so let's call this one private n or four or one arrow and then this one will again get a request HTTP request not interceptor so just the values that our other function already has as well we will pass this through this one as well and then next is the HTTP handler okay let's do a little luck should refresh token and then we can check or we can return this that of course we need to make a request now so back to our constructor and injecting the service private fake HTTP fake HTTP service returning this dot fake HTTP GET token and you will of course have also a route for this in place you get your tote and then perform some operation in here it doesn't really matter right now and now this function can simply be used right in here so this start handled 401 we need a request and we need the next one and then this function is happy again since catch error again needs to return an observable so we return our own observable yeah I think we just haven't implemented it right now so let's go here in general this now really depends on your application but as an idea for what you could do once you get back the result for the token you could call switch map which basically switches to another observable so in switch map result and our result now has the token since this is my poop's that is not my API where's my API I'm if somebody's seen my API I don't know where it is but it actually returns a token so we will lock this out and you could for example store the token now but what's more important is to actually grab the token which is in my response at this position and then attach this totem to the initial request so request equals request Cologne we can simply clone the initial request then said a param owl in my example edit as a query param so in most cases for JSON web token authentication it is of course in the header field for the authorization but that's also something you could set right in this place and then just like we did before return next please handle our request and then this have function is happy and hopefully if we did everything correctly this one is now happy as well the code if you look at this the full code it's really kind of complicated and really advanced rxjs stuff but if you go through this one one by one everything makes sense they catch arrow blocks the retry blocks the switch map to when you observe well everything really comes together and makes sense in the end if you go through it one by one so let's try our request first of all get success just to show we can get the success we can show toast if it completes and we have the loading indicator while or request heaven's get failed will simply fail about three times are we trying every one second and once we're there we will get the final alert that something went wrong with the API now get retry failed as before still works as advertised it will complete on the third try there we go and now get authentication failed is interesting since we should refresh our toe we're in switch map we're getting the token and then finally our function completes with the data of the initial call so homepage coming out to the home page to show you there we go this would be just like a regular HTTP call and the token has expired then the Interceptor notices that the token is expired so we get a 401 bit in the error response we will handle it by making a new request getting a new token saving it locally attaching it to the request and then handling the request once again and then we will be back at the top Cola basically here retry when is really not really necessary since the request now completes we don't have catch arrow we have a finalized block to dismiss loading and everything happens in the background automatically so I hope you enjoyed this a bit more advanced topic about rxjs and HDPE interceptors if you got any questions as always please leave them below if you want to see anything else in place or in the video like a real total reflect flow or a Jason Webb talk or whatever it might be just let me know make sure that you also subscribe to this channel for our regular videos tutorials what is coming in here and of course check out the ionic Academy which is my online school to help you with everything ionic I hope you enjoyed this video I will catch you next time so happy coding cyber [Music]
Info
Channel: Simon Grimm
Views: 9,542
Rating: undefined out of 5
Keywords: ionic 4, ionic framework, ionic 4 tutorial, ionic 4 course, learn ionic, learn ionic 4, angular, ionic angular, ionic 4 angular, ionic guide, cross platform, hybrid app, ionic4, ionic 4 app, ionic for beginners, ionic 4 for beginners, ionic course, angular 7, angular 7 tutorial, ionic, cordova, javascript
Id: IJWCpa_-MeU
Channel Id: undefined
Length: 25min 17sec (1517 seconds)
Published: Tue Feb 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.