1
00:00:02,280 --> 00:00:07,650
So now with all these things we learned about browser support and how to determine the correct support

2
00:00:07,650 --> 00:00:08,440
level,

3
00:00:08,520 --> 00:00:15,150
let's learn about some strategies on how you can build a web application that works in a broad variety

4
00:00:15,150 --> 00:00:16,230
of browsers

5
00:00:16,230 --> 00:00:22,740
and there, one thing we could do is we could use feature detection and provide fallbacks if a certain

6
00:00:22,740 --> 00:00:26,870
feature is not available or not supported by a browser.

7
00:00:26,880 --> 00:00:29,610
Let's say we want to use the clipboard API,

8
00:00:29,610 --> 00:00:34,440
that's a relatively modern browser API that allows us to interact with the user's clipboard,

9
00:00:34,470 --> 00:00:40,320
so the thing you use with copy and pasting. If we search for clipboard API and we check the MDN

10
00:00:40,380 --> 00:00:44,500
article and we scroll down, we see browser support is not looking that great.

11
00:00:44,640 --> 00:00:47,830
It works on FIrefox and Chrome,

12
00:00:47,850 --> 00:00:50,620
we don't know whether it works in Safari,

13
00:00:50,700 --> 00:00:53,520
it does not work in Edge and not in Internet Explorer.

14
00:00:53,520 --> 00:00:54,360
Now let's also check

15
00:00:54,360 --> 00:00:56,460
caniuse.com,

16
00:00:56,610 --> 00:00:58,150
let's search for a clipboard there

17
00:00:59,100 --> 00:01:06,590
and there if we scroll down a bit, here to the clipboard API, we see the same picture. For Safari

18
00:01:06,590 --> 00:01:13,010
it's simply not clear whether it's supported but we definitely know it's not supported in Edge or Internet

19
00:01:13,010 --> 00:01:14,170
Explorer,

20
00:01:14,270 --> 00:01:16,760
now in Chrome and FIrefox however it does work.

21
00:01:17,270 --> 00:01:21,080
Now how can it be not clear for Safari?

22
00:01:21,080 --> 00:01:24,340
Well it's not about people not testing it there,

23
00:01:24,380 --> 00:01:26,760
it is about how the browser vendors,

24
00:01:26,780 --> 00:01:32,450
so the people working on Safari, how they communicate features they want to support and if they haven't

25
00:01:32,450 --> 00:01:39,170
communicated any information regarding their plans on whether they want to support the clipboard API

26
00:01:39,170 --> 00:01:42,020
or not, then this is treated as unknown,

27
00:01:42,020 --> 00:01:46,910
we don't know what their plans are we don't know if they're about to implement it, if it should be working

28
00:01:46,910 --> 00:01:50,230
and it's not working due to a bug or anything like that.

29
00:01:50,240 --> 00:01:53,800
So this could be a reason for this feature being unknown

30
00:01:53,870 --> 00:02:01,040
rather than being marked as not supported. Now this also is a feature that might be nice to have in an application

31
00:02:01,280 --> 00:02:06,490
to simplify some process for the user for example but that's not a must-have,

32
00:02:06,500 --> 00:02:12,170
so therefore here we could use feature detection and then simply provide two routes. We can check if

33
00:02:12,170 --> 00:02:17,180
the feature is available and I will of course show you how that works and if it is available, we execute

34
00:02:17,180 --> 00:02:19,880
the code that relies on this feature to exist,

35
00:02:19,880 --> 00:02:26,360
otherwise if it's not available, we execute some fallback code or we show an error message to the

36
00:02:26,360 --> 00:02:31,720
user, we give the user another way of letting him use our application.

37
00:02:31,730 --> 00:02:38,270
So basically what we try to do is we want avoid that the application crashes and instead just provide

38
00:02:38,300 --> 00:02:44,810
two different code branches that can execute based on the existence of this feature or not

39
00:02:44,870 --> 00:02:49,610
and for that I got a simple application which you find attached, it has a button, do something,

40
00:02:49,610 --> 00:02:50,980
it's this project setup.

41
00:02:51,110 --> 00:02:54,620
It uses some tooling as you learned it in the tooling section,

42
00:02:54,620 --> 00:03:00,710
you need to run npm run build: dev to spin up that development server which uses webpack

43
00:03:00,710 --> 00:03:02,450
dev server behind the scenes.

44
00:03:02,480 --> 00:03:08,060
We will work in app.js here and our code will be output in the assets folder thereafter from which

45
00:03:08,060 --> 00:03:14,800
we also import it and then in the end, we'll get this button here and our working code.

46
00:03:14,840 --> 00:03:20,420
Now let's say we want to use the clipboard API and therefore temporarily, I'll add a paragraph here, some

47
00:03:20,420 --> 00:03:21,080
text

48
00:03:21,080 --> 00:03:28,790
you could copy and we want to make sure that when this button is pressed, copy, we put this text into

49
00:03:28,790 --> 00:03:29,540
the clipboard,

50
00:03:29,540 --> 00:03:36,680
so the same thing should happen as if you manually mark this and press control c, that's what we want

51
00:03:36,680 --> 00:03:38,230
to replicate here.

52
00:03:38,360 --> 00:03:39,940
Now to make it work, let's go to app.js

53
00:03:39,950 --> 00:03:42,450
and you've got some starting code here which selects a button,

54
00:03:42,830 --> 00:03:51,230
let's also select the text paragraph here with document query selector and then just the first

55
00:03:51,230 --> 00:03:54,460
paragraph we find because that's the only paragraph we have

56
00:03:54,710 --> 00:04:01,970
and now we can get our text here by accessing text paragraph.text content,

57
00:04:01,970 --> 00:04:05,180
this is the text which is written in there.

58
00:04:05,180 --> 00:04:11,320
Now we want to use the clipboard API and place that in the clipboard of the user.

59
00:04:11,320 --> 00:04:14,130
Now for that, we can use navigator.clipboard,

60
00:04:14,150 --> 00:04:19,370
use the right text method there and then this needs a data piece here,

61
00:04:19,430 --> 00:04:26,390
here I'll just put in my text because it wants a string and thereafter, this will give us a promise.

62
00:04:26,550 --> 00:04:33,760
So here, we can listen to the result, maybe console log it and see whether we get something there and

63
00:04:33,760 --> 00:04:40,570
maybe also add a catch method and you could use async await instead of course and also log any error

64
00:04:40,600 --> 00:04:41,970
we might be getting.

65
00:04:41,980 --> 00:04:46,140
So now we have some code here which uses the navigator, the clipboard API.

66
00:04:46,330 --> 00:04:52,060
If we save that and I go back here and I click copy, get undefined being logged here

67
00:04:52,150 --> 00:04:57,910
but now if I go into the console here and I hit command v or control v to paste in what is in my

68
00:04:57,910 --> 00:05:02,390
clipboard, you see indeed that text here was put into my clipboard,

69
00:05:02,440 --> 00:05:04,530
I never manually control c'ed it,

70
00:05:04,660 --> 00:05:10,330
I can prove it by marking this and hitting copy, control c and now again if I click the copy button

71
00:05:10,570 --> 00:05:15,220
and I press control v here, you see again I have this text in my clipboard. So this works

72
00:05:15,220 --> 00:05:17,530
and of course it works because I'm in Chrome here

73
00:05:17,640 --> 00:05:21,880
and as we can tell, Chrome supports the clipboard API.

74
00:05:21,880 --> 00:05:22,960
Now that's nice

75
00:05:22,990 --> 00:05:25,070
but not everyone is using Chrome,

76
00:05:25,090 --> 00:05:28,420
let's see if the same example works in Safari,

77
00:05:28,420 --> 00:05:33,520
if you are a Windows user, you can simply try Edge. So here I am also opening up the developer tools

78
00:05:33,520 --> 00:05:39,460
in the console and click copy here and now you see I'm getting an error, undefined is not an object, evaluating

79
00:05:39,460 --> 00:05:45,280
navigator.clipboard write text and indeed if I tried to paste in what I copied, it's still my URL.

80
00:05:45,550 --> 00:05:50,980
So in Safari, this does not work and if you tested it on Edge, it also doesn't work. Well at sometime

81
00:05:51,040 --> 00:05:52,110
in the future it might work

82
00:05:52,120 --> 00:05:54,980
but at the point of time I'm recording this, this is not working

83
00:05:55,060 --> 00:05:59,610
and in the future, other features will not be working in one or the other browser.

84
00:05:59,650 --> 00:06:06,850
So at the moment, the clipboard API is not working in Safari and not working in Edge for example.

85
00:06:06,850 --> 00:06:12,130
Now right now the problem we have with that is that we got an error that is being thrown here and this

86
00:06:12,130 --> 00:06:15,250
might simply crash our application, like it does here,

87
00:06:15,250 --> 00:06:21,670
this is not coming from inside our catch handler because it's not the copy action that went wrong,

88
00:06:21,670 --> 00:06:27,130
instead it's coming from an earlier point of time because we try to call a method on undefined because

89
00:06:27,130 --> 00:06:32,410
in Safari, navigator.clipboard yields undefined and if you try to call a method on that, you get

90
00:06:32,410 --> 00:06:33,040
an error

91
00:06:33,040 --> 00:06:37,630
so your application crashes and that's something we of course don't want.

92
00:06:37,630 --> 00:06:42,910
Now we could wrap this with try catch to catch this error but that quickly gives us code which is

93
00:06:42,910 --> 00:06:44,200
a bit dirty,

94
00:06:44,200 --> 00:06:46,060
so instead let's do something different,

95
00:06:46,060 --> 00:06:49,390
let's use feature detection and this is very simple,

96
00:06:49,510 --> 00:06:51,700
we want to use navigator.clipboard.

97
00:06:51,700 --> 00:06:52,740
Now what does it yield

98
00:06:52,740 --> 00:07:00,250
if this is not supported? It gives us undefined. So we can check if navigator.clipboard and you learned

99
00:07:00,280 --> 00:07:05,830
that undefined will be falsy, if this gives us an object or anything else we can work with it will

100
00:07:05,830 --> 00:07:09,130
be truthy and therefore we'll make it into this if block

101
00:07:09,160 --> 00:07:12,960
if this is not undefined, so we'll make it into this if block

102
00:07:12,970 --> 00:07:14,280
If this is available.

103
00:07:14,470 --> 00:07:20,800
So now we can take the code that relies on the availability and move that into that if block and now

104
00:07:20,800 --> 00:07:24,610
this code only runs in browsers where it actually is supported.

105
00:07:24,610 --> 00:07:31,020
If we save that and we go back and I click copy here, in Chrome of course it still works, now let me clear that

106
00:07:31,020 --> 00:07:33,370
and copy undefined instead

107
00:07:33,370 --> 00:07:38,130
and now if I go to Safari and I click copy here, we don't get an error anymore.

108
00:07:38,130 --> 00:07:39,410
Of course it also doesn't work,

109
00:07:39,410 --> 00:07:43,570
I didn't put it into my clipboard but the app is not breaking anymore

110
00:07:43,830 --> 00:07:49,920
and now we can provide some fallback code for browsers where it is not supported, simply by providing

111
00:07:49,920 --> 00:07:50,040
an

112
00:07:50,040 --> 00:07:51,260
else branch here

113
00:07:51,450 --> 00:07:58,500
and then the simplest fallback would be that we show an error message, feature not available please

114
00:07:58,500 --> 00:08:05,040
copy manually or depending on which feature we're trying to use and on what we're trying to build, we

115
00:08:05,040 --> 00:08:12,270
might be able to offer an alternative route. Maybe we can go into that paragraph and preselect the content

116
00:08:12,270 --> 00:08:18,420
at least, so that the user just has to press control and c, that might be a possible improvement or

117
00:08:18,420 --> 00:08:23,620
we can do anything else, that really comes down to the question of what you're trying to build.

118
00:08:23,700 --> 00:08:28,950
Being able to provide some fallback code here and only execute the code that uses that feature when

119
00:08:28,950 --> 00:08:34,560
you need it is a great step in the right direction however and therefore feature detection and fallback

120
00:08:34,560 --> 00:08:41,820
code is a great way of using certain features that might be nice to have but are not really essential

121
00:08:41,880 --> 00:08:48,270
for your application, which means the rest of your application might work fine even if users can't use

122
00:08:48,270 --> 00:08:54,240
this convenience button here because for now in Safari, they would simply get that alert. Checking for

123
00:08:54,240 --> 00:09:00,810
feature availability and providing potential fallback code is also viable for features that might be

124
00:09:00,810 --> 00:09:07,320
crucial for your application, even if you can't work around it with some fallback code and even if your

125
00:09:07,380 --> 00:09:14,850
application really depends on the availability of a certain feature, you can at least use feature detection

126
00:09:14,940 --> 00:09:21,480
and fallback code to show the user an error message prompting the user to switch to a different browser

127
00:09:21,480 --> 00:09:26,880
for example, even that is better than just failing silently.

128
00:09:26,880 --> 00:09:32,340
Also keep in mind that users of course don't visit the developer tools, so they don't even see the error

129
00:09:32,340 --> 00:09:36,870
message in the console and even if they would, it might not tell them anything.

130
00:09:36,870 --> 00:09:40,740
So showing at least some error message is better than doing nothing,

131
00:09:40,740 --> 00:09:47,430
so even for a vital feature where you can't work around in your fallback code, having such a detection

132
00:09:47,430 --> 00:09:52,680
strategy and showing an alert or an error is better than doing nothing.
