1
00:00:02,380 --> 00:00:06,060
So we saw promise chaining in action and really important to emphasize here,

2
00:00:06,070 --> 00:00:10,210
you don't have to return a promise in here, you can return any kind of data and it will be converted

3
00:00:10,210 --> 00:00:12,100
to a promise and wrapped into a promise,

4
00:00:12,100 --> 00:00:16,990
the core idea of promise chaining is that you can have step after step and this step here for example,

5
00:00:16,990 --> 00:00:21,150
the second one, will only execute once this step is done, so once this promise is done,

6
00:00:21,160 --> 00:00:25,890
we make it into this step and then once whatever we return here which is wrapped into a promise,

7
00:00:25,900 --> 00:00:27,480
if it is not a promise already,

8
00:00:27,520 --> 00:00:31,960
once this is done, we make it into this step, a very powerful concept.

9
00:00:31,960 --> 00:00:36,640
Now let's have a look at errors because of course, things can always go wrong,

10
00:00:36,640 --> 00:00:42,040
for example when we're getting the position, we have this error callback in our promisified

11
00:00:42,100 --> 00:00:42,940
version here.

12
00:00:42,940 --> 00:00:47,920
Now what if we have that arrow case, because for example permission is not granted?

13
00:00:47,980 --> 00:00:53,140
Well then previously, we would handle our error here but now since I have moved this into a promise, I want

14
00:00:53,140 --> 00:00:57,950
to pass this onto my promise chain so that we can somehow handle it here.

15
00:00:57,970 --> 00:01:03,970
Now that is done with this second argument, this configuration function for the promise constructor gets

16
00:01:04,030 --> 00:01:09,190
the reject argumen. We can call reject here inside of the arrow callback

17
00:01:09,430 --> 00:01:14,070
and for example pass our error object into reject.

18
00:01:14,230 --> 00:01:18,920
Now what reject will do is it will mark the promise as failed,

19
00:01:18,970 --> 00:01:22,570
I mentioned that a promise can be pending or resolved,

20
00:01:22,570 --> 00:01:25,210
it's pending whilst we're waiting for it to be resolved

21
00:01:25,210 --> 00:01:31,080
basically, once we resolved it, we can set it back to pending by returning something in the then block.

22
00:01:31,100 --> 00:01:33,510
Now there is another state and that is the

23
00:01:33,590 --> 00:01:38,750
failed state basically, that we have an error. So the promise is now not resolved,

24
00:01:38,780 --> 00:01:41,890
it's not pending but it has an error. Now

25
00:01:41,960 --> 00:01:48,110
errors are not handled with the normal then functions here, with these functions you pass to then I should

26
00:01:48,110 --> 00:01:51,620
say, instead then takes a second argument.

27
00:01:51,620 --> 00:01:57,590
The first argument here is the callback function that should be executed if the promise resolves,

28
00:01:57,590 --> 00:02:02,060
the second argument is the potential error function we might have.

29
00:02:02,060 --> 00:02:05,620
So here, we could expect our error object, you can name it however you want here

30
00:02:05,840 --> 00:02:11,990
and for example log that here or send it to your own server where you want to write some logs or do

31
00:02:11,990 --> 00:02:13,400
whatever you want.

32
00:02:13,520 --> 00:02:16,520
So that's a second argument I'm passing to the then method here,

33
00:02:16,610 --> 00:02:23,000
it's a second function I'm passing to then, the first function is the success case when the promise resolves,

34
00:02:23,000 --> 00:02:29,900
the second argument here is the failure case, when a promise does not resolve but instead rejects.

35
00:02:29,900 --> 00:02:38,540
So now if we go back and reload and I click block here, we see that error here for example, user denied

36
00:02:38,540 --> 00:02:40,310
geolocation. We also got this output,

37
00:02:40,370 --> 00:02:44,650
I'll come back to it in a second but for now we see that the error is being output here,

38
00:02:44,750 --> 00:02:47,440
so this code executes here.

39
00:02:47,510 --> 00:02:53,030
Now you might argue that we're losing some of the benefits we gained with promises

40
00:02:53,030 --> 00:02:59,450
if we have a second argument here, a second function. Whilst it's not nested into another callback, we

41
00:02:59,450 --> 00:03:01,500
have more callbacks next to each other

42
00:03:01,550 --> 00:03:06,890
and whilst this is perfectly fine to use, you have an alternative to that, you have another methods

43
00:03:06,890 --> 00:03:08,710
you can add to your promise chain,

44
00:03:08,810 --> 00:03:13,540
for example here and that's the catch method.

45
00:03:13,540 --> 00:03:19,390
Now the catch method can be added on a promise and you can add it anywhere in this chain, right after

46
00:03:19,390 --> 00:03:25,630
executing this function which returns a promise or anywhere thereafter, though the exact position doesn't

47
00:03:25,630 --> 00:03:26,380
matter.

48
00:03:26,380 --> 00:03:33,010
Let's for example add it here after the first then block, add catch here and we have a then block thereafter

49
00:03:33,040 --> 00:03:35,260
which belongs to the same chain still

50
00:03:35,320 --> 00:03:38,420
and here you can now have your error function.

51
00:03:38,440 --> 00:03:44,720
Now let's try if it works before we dive into what it does. If I click track me and I block, we get that

52
00:03:44,740 --> 00:03:45,580
error output

53
00:03:45,580 --> 00:03:46,640
so it works

54
00:03:46,750 --> 00:03:48,270
but what does it do?

55
00:03:48,640 --> 00:03:54,220
Catch actually does exactly the same as if you pass it as a second argument here to one of your then

56
00:03:54,220 --> 00:03:54,520
block,

57
00:03:54,520 --> 00:03:58,170
so it's really just an alternative to that but both approaches,

58
00:03:58,240 --> 00:04:04,150
no matter if you use the second argument or a catch block works such that they catch any errors, any

59
00:04:04,150 --> 00:04:11,890
rejections produced anywhere in your promise chain prior to this catch block or prior to the place

60
00:04:11,890 --> 00:04:14,280
where you added it as a second argument.

61
00:04:14,290 --> 00:04:19,930
So if we had more then blocks here, which we don't have in this promise because it doesn't make sense

62
00:04:19,930 --> 00:04:21,220
there, it won't work there

63
00:04:21,310 --> 00:04:27,820
but if we had a longer promise chain with multiple then blocks, then no matter if you have an error here

64
00:04:28,180 --> 00:04:36,310
or in the promise returned here or here or here, if any of these promises rejects, this logic will run

65
00:04:36,550 --> 00:04:39,460
or the logic in the nearest second argument.

66
00:04:39,460 --> 00:04:45,280
So if this promise rejects for example, it's not just the case that this then block will be skipped,

67
00:04:45,280 --> 00:04:51,010
instead all then blocks thereafter will be skipped until we reach a catch block or a second argument

68
00:04:51,010 --> 00:04:52,600
to handle the error.

69
00:04:52,600 --> 00:05:00,150
So in this scenario here which will work, this then block is skipped if this promise which was returned

70
00:05:00,150 --> 00:05:02,770
by get position, if this rejects,

71
00:05:02,820 --> 00:05:10,200
so this then block is skipped and instead we make it into this catch block but this then block will then

72
00:05:10,230 --> 00:05:11,540
execute again,

73
00:05:11,610 --> 00:05:17,350
so the catch block, this catch method does not cancel the entire promise chain,

74
00:05:17,370 --> 00:05:25,210
instead it just does its thing and you can even return something new here which can be a promise or

75
00:05:25,240 --> 00:05:30,820
some other data that will be wrapped into a promise, just as it's the case in the then method and now

76
00:05:30,910 --> 00:05:33,990
any then blocks thereafter will continue to work.

77
00:05:34,270 --> 00:05:39,860
So the positioning of the catch block doesn't matter, if you want to kind of cancel the promise chain,

78
00:05:40,030 --> 00:05:45,340
you have to move it to the end of all your then blocks because only then you make sure that if one of

79
00:05:45,340 --> 00:05:49,750
them rejects, the other ones are skipped and you make it into catch.

80
00:05:49,750 --> 00:05:55,000
If you add catch somewhere in the middle, then all prior ones are skipped

81
00:05:55,000 --> 00:06:00,620
if one of them rejects but then blocks after catch will be executed.

82
00:06:01,120 --> 00:06:08,770
So here in catch, what happens is we cancel or we skip all previous then blocks if one of them rejects

83
00:06:08,770 --> 00:06:10,660
but then here we return new data

84
00:06:10,660 --> 00:06:15,490
for example, even if you don't return anything, you return undefined basically

85
00:06:15,700 --> 00:06:18,670
and that sets the promise back to pending

86
00:06:18,670 --> 00:06:25,090
and if you have more then blocks thereafter, those will execute once the pending promise resolves again.

87
00:06:25,090 --> 00:06:28,570
So it does not cancel the promise, it allows it to continue.

88
00:06:28,570 --> 00:06:37,020
So here for example if I return on we go and you will see I click block, we print on we go here, we still

89
00:06:37,020 --> 00:06:41,520
get undefined because position data is undefined because we skipped this then block

90
00:06:41,520 --> 00:06:42,450
as I explained

91
00:06:42,450 --> 00:06:47,440
but data here is what I returned here in the catch block and that's not a bug,

92
00:06:47,450 --> 00:06:52,730
that's of course very useful because it allows you to structure your chain such that certain parts

93
00:06:52,730 --> 00:06:59,780
of it can be skipped if necessary but it doesn't necessarily crash entirely just because one part failed.

94
00:06:59,780 --> 00:07:06,030
If you wanted to crash entirely, you can always force that by moving catch to the end of course.

95
00:07:06,320 --> 00:07:11,750
If you have catch somewhere in the middle, then the promise chain continues after catch and of course,

96
00:07:11,960 --> 00:07:17,740
you could have another catch in there to handle an error in here because if this rejects for some reason,

97
00:07:17,870 --> 00:07:23,810
this catch block which came before it will not do anything, you would need a new catch block or a new

98
00:07:23,840 --> 00:07:29,650
second argument to handle any errors here or in other then blocks thereafter.

99
00:07:29,660 --> 00:07:33,360
So this is error handling and how promise chaining works with errors,

100
00:07:33,470 --> 00:07:39,680
really important to understand that, gives you a lot of power and all the flexibility you need to write

101
00:07:39,680 --> 00:07:43,880
great applications which also can deal with errors in a graceful way.
