1
00:00:02,250 --> 00:00:06,060
With this, this project is pretty much finished

2
00:00:06,060 --> 00:00:11,090
but there is another cool thing you can do with Javascript which many people wouldn't expect or which

3
00:00:11,110 --> 00:00:14,160
might be strange when you hear it the first time.

4
00:00:14,160 --> 00:00:19,460
You can also create and run a script with Javascript,

5
00:00:19,530 --> 00:00:23,010
now let me show you how that would work. In app.js, let's go to init,

6
00:00:23,790 --> 00:00:24,890
so to app init

7
00:00:24,930 --> 00:00:34,900
here at the very bottom, this static method and in there, you can create a script dynamically in Javascript.

8
00:00:34,950 --> 00:00:36,470
How would that look like?

9
00:00:36,480 --> 00:00:44,280
Well let's create a new constant for example, some script and we create it with document create element

10
00:00:44,400 --> 00:00:47,480
like we always did but now we create a script element.

11
00:00:47,490 --> 00:00:52,950
Remember, there are script tags in HTML and then of course you can create such a script tag as

12
00:00:52,950 --> 00:00:55,330
well with create element.

13
00:00:55,380 --> 00:01:01,900
So now, some script is in the end a script tag which we created.

14
00:01:01,910 --> 00:01:11,360
Now we can insert some text content here and for example enter alert Hi there to throw an alert, this

15
00:01:11,360 --> 00:01:13,380
is valid Javascript code right.

16
00:01:15,140 --> 00:01:21,400
Now we just need to add it to our document and we can do that by going to document and there in the head

17
00:01:21,410 --> 00:01:27,760
maybe, append our script which is stored in the some script constant.

18
00:01:27,760 --> 00:01:34,540
The result is that when init runs, our script here should be added. Let's save that and reload

19
00:01:34,730 --> 00:01:37,790
and indeed here is my alert and if I save this or click

20
00:01:37,800 --> 00:01:43,610
OK, then we're done and we see the content because if we now inspect the render DOM in the head, indeed

21
00:01:43,610 --> 00:01:45,590
we have that script here,

22
00:01:45,590 --> 00:01:51,710
so you can create and add scripts dynamically. Now for scripts like this, this might be nice but I'm not

23
00:01:51,710 --> 00:01:56,840
sure you really need that because if you just want to execute some script code, you can just write it

24
00:01:56,840 --> 00:02:04,520
like right here, right? It's more interesting if you have some other script file which you only want to

25
00:02:04,520 --> 00:02:07,060
download at a certain point of time,

26
00:02:07,160 --> 00:02:14,050
so where you want to control when the browser loads this script from inside your Javascript code. So

27
00:02:14,050 --> 00:02:20,080
let's say we had another script here, analytics.js where we just send some analytics data.

28
00:02:20,110 --> 00:02:23,980
So for now I'll just console log sending analytics here,

29
00:02:24,100 --> 00:02:25,670
very simple script.

30
00:02:25,720 --> 00:02:32,550
Now if we go to our HTML file and we import this here with script source, then we of course run this

31
00:02:32,560 --> 00:02:34,180
right away.

32
00:02:34,320 --> 00:02:40,140
Of course I can add defer here but that means once the parsing is done, this script executes.

33
00:02:40,140 --> 00:02:46,590
Now maybe you have some app where you only want to run your script after something happens, so for example

34
00:02:46,620 --> 00:02:50,170
after the user click the button or anything like that.

35
00:02:50,220 --> 00:02:58,880
So for that, I'll add a new static method here, start analytics and in there,

36
00:02:58,900 --> 00:03:02,550
I now want to dynamically load that script. For this

37
00:03:02,560 --> 00:03:11,480
we can again add a new script element with document create element script

38
00:03:11,800 --> 00:03:14,750
but now I don't add any text content to it,

39
00:03:14,770 --> 00:03:17,470
instead you can set analytics scripts.source,

40
00:03:17,470 --> 00:03:23,740
you can set the source property just as you can set the source attribute here and this will basically

41
00:03:23,740 --> 00:03:26,500
tell the browser where to find that script.

42
00:03:26,500 --> 00:03:32,860
Then here, you should set up a path as you would do it here in your HTML file, so not seen relative

43
00:03:32,890 --> 00:03:38,440
from the Javascript file but really just as it would be added to the HTML file because that is where

44
00:03:38,440 --> 00:03:40,490
it will be executed in the end,

45
00:03:40,570 --> 00:03:44,690
so that would be assets/scripts/analytics.js.

46
00:03:44,730 --> 00:03:51,520
in this case and then also maybe add the defer attribute or the defer property and set this

47
00:03:51,520 --> 00:03:56,920
to true so that this is only loaded after all HTML parsing has been done.

48
00:03:56,950 --> 00:04:04,540
Now I just need to add this here to my head with document head for example and then append my analytics

49
00:04:04,570 --> 00:04:10,180
script and now whenever we call start analytics, this script should be loaded and executed

50
00:04:10,630 --> 00:04:16,360
and now we could do this of course in the init method here but we could also say we want to do that

51
00:04:16,810 --> 00:04:18,920
whenever one of our buttons here is clicked,

52
00:04:18,970 --> 00:04:23,550
then we just should make sure that we don't add this same script multiple times.

53
00:04:23,590 --> 00:04:27,800
So here to keep it simple for now, I'll just do it when init runs,

54
00:04:27,820 --> 00:04:30,760
so here I'll call this start analytics and

55
00:04:30,780 --> 00:04:36,440
if I now save that and we reload and I open the console, you see sending analytics here.

56
00:04:36,490 --> 00:04:40,720
Now of course this executes right away when the app starts because I call it here in init,

57
00:04:40,750 --> 00:04:46,570
nonetheless this script was actually added dynamically through Javascript and you could have added it

58
00:04:46,810 --> 00:04:50,470
at any point of time, not just when this page loads.

59
00:04:50,470 --> 00:04:57,790
For example you can go to the index.html file and in there at the very bottom, add a footer where we can

60
00:04:57,790 --> 00:05:02,070
add a button where you could say start analytics.

61
00:05:02,070 --> 00:05:07,290
Now of course you typically wouldn't add such a button to your application because most users will probably

62
00:05:07,290 --> 00:05:13,140
not start analytics on their own but it can be useful for us here to prove that this script really only

63
00:05:13,140 --> 00:05:16,500
is added and executed when your Javascript code runs.

64
00:05:16,500 --> 00:05:25,740
So I'll give this an ID, start analytics button and with that ID, we can go back to app.js and then

65
00:05:25,740 --> 00:05:29,040
in here, in init, not do this here,

66
00:05:29,040 --> 00:05:35,670
don't start the script like that but instead, reach out with get element by adding to our button so that

67
00:05:35,670 --> 00:05:44,020
whilst the start analytics btn ID which I assign here and then add an event listener to this button

68
00:05:44,560 --> 00:05:48,010
so that upon a click, we execute this start

69
00:05:48,010 --> 00:05:50,080
analytics.

70
00:05:50,300 --> 00:05:56,150
Now if we save that, you will not see it send analytics when I reload but you'll see it once I click

71
00:05:56,150 --> 00:05:58,290
this button here at the bottom,

72
00:05:58,310 --> 00:06:05,300
now you see that as soon as I press the button. Now the button is a bit strangely positioned here simply because

73
00:06:05,300 --> 00:06:10,370
I'm zoomed in that far and I have given it an absolute positioning at the bottom, if I would zoom out a

74
00:06:10,370 --> 00:06:10,960
bit more,

75
00:06:11,030 --> 00:06:13,900
this looks better but it's not so much about the styling here,

76
00:06:13,940 --> 00:06:20,060
the behavior is the important thing. In the developer tools, you can also go to the network tab and in there,

77
00:06:21,810 --> 00:06:23,380
you see all the files that were loaded.

78
00:06:23,380 --> 00:06:28,570
If I now reload, you'll see everything is loaded but the analytics Javascript file is not one of the

79
00:06:28,570 --> 00:06:30,460
loaded files.

80
00:06:30,460 --> 00:06:36,970
If I click on start analytics though, you see now it's getting downloaded here, super fast of course because

81
00:06:36,970 --> 00:06:41,390
it's a small file but only once I click the button.

82
00:06:41,470 --> 00:06:47,770
So this is pretty neat and this is how you can add and run scripts dynamically from inside Javascript.

83
00:06:47,770 --> 00:06:51,180
Now one important note about adding scripts dynamically like this,

84
00:06:51,310 --> 00:06:54,530
it's a powerful feature but of course you want to do it with care,

85
00:06:54,550 --> 00:07:00,820
you should especially be careful when it comes to dynamically rendering user created scripts because

86
00:07:00,820 --> 00:07:07,690
that opens you up to some attacks here and it is something we'll have a closer look at in the security

87
00:07:07,690 --> 00:07:13,810
section later down in the course, where we talk about attacks like cross-site scripting attacks which

88
00:07:13,810 --> 00:07:17,360
in the end try to inject malicious code into your code.

89
00:07:17,440 --> 00:07:24,850
So if you dynamically add a script, make sure you don't do it based on some user entered content or at

90
00:07:24,850 --> 00:07:29,020
least validate that content and sanitize it before you execute it

91
00:07:29,050 --> 00:07:32,770
but again we'll have a closer look at this topic in the security module.
