1
00:00:02,090 --> 00:00:06,290
So last but not least, let's explore the functional programming style. For this,

2
00:00:06,350 --> 00:00:12,080
I'll create a new file here, functional.js and of course import this here in the index.html file,

3
00:00:12,560 --> 00:00:14,040
functional.

4
00:00:14,150 --> 00:00:20,720
The idea behind functional programming now is that we organize our code around functions, so we

5
00:00:20,720 --> 00:00:28,190
can still then reuse and share logic by simply sharing a function, by exporting it and importing it in

6
00:00:28,190 --> 00:00:29,420
another file and so on.

7
00:00:30,350 --> 00:00:38,120
So how could we split this application here into a functionally written application?

8
00:00:38,190 --> 00:00:42,860
It can be hard to think about this if you're relatively new in programming.

9
00:00:42,930 --> 00:00:48,600
My personal experience shows that object oriented programming is relatively easy to pick up because

10
00:00:48,600 --> 00:00:50,180
it's close to the real world

11
00:00:50,190 --> 00:00:57,060
so to say, we think in objects and that's how we think about the real world as well. The procedural style

12
00:00:57,090 --> 00:01:02,460
also is not too hard because we execute code step-by-steps and therefore all we have to do is that we

13
00:01:02,460 --> 00:01:06,200
have to think about what we want to do in our application step-by-step,

14
00:01:06,200 --> 00:01:13,750
so what should happen when and then this code is basically writing itself. Now in the functional world,

15
00:01:13,890 --> 00:01:20,760
it's a bit like in the object oriented world, we think about the different things that make up our application

16
00:01:20,790 --> 00:01:28,200
but the things are now not objects but instead of different logical blocks, something like a validate

17
00:01:28,200 --> 00:01:34,980
function, a function to get access to a DOM element, a function to extract user input, a function to create

18
00:01:34,980 --> 00:01:37,830
a new user, a function to greet a user.

19
00:01:37,830 --> 00:01:46,910
So basically we try to split our code into the different logical blocks we have here. So in functional.js,

20
00:01:46,910 --> 00:01:51,310
how could we get started because maybe that helps us understand how it works?

21
00:01:52,000 --> 00:01:55,640
It still starts with us getting access to the form right,

22
00:01:55,660 --> 00:02:02,520
we need access to the form so that we can listen to the form submission. To get access here, we could

23
00:02:02,520 --> 00:02:06,510
write a new function, connect form, name is up to you

24
00:02:06,990 --> 00:02:12,660
and by the way you can write this function in any way you want, in this function declaration style here,

25
00:02:12,660 --> 00:02:19,260
you could also write it as a function expression or of course, you could use an arrow function here if

26
00:02:19,260 --> 00:02:19,970
you wanted to,

27
00:02:19,990 --> 00:02:21,410
that all works, here

28
00:02:21,450 --> 00:02:27,750
I'll just write it like this. So connect form, just like this without any parameters for now

29
00:02:27,990 --> 00:02:34,320
and in there I want to get access to my form and I do so by calling document get element by ID user-input

30
00:02:34,350 --> 00:02:41,800
and thereafter I will reach out to my form and add a submit event listener here and then,

31
00:02:41,850 --> 00:02:47,620
then what? Then I want to point at a function that should execute when the form is submitted.

32
00:02:47,820 --> 00:02:55,350
So maybe let's add a new function here, the signupHandler which gets this event object which calls event

33
00:02:55,350 --> 00:02:56,590
prevent default,

34
00:02:56,610 --> 00:03:00,540
it will also do more than that but this is something we definitely need to do

35
00:03:00,540 --> 00:03:02,160
and then I point at it here.

36
00:03:02,190 --> 00:03:06,510
This is something we could do but it's not the perfect way of setting this up.

37
00:03:06,990 --> 00:03:14,610
Instead the idea or the core philosophy you really should embrace when writing functional code is that

38
00:03:14,610 --> 00:03:21,600
your functions should be pure and all the data they work with is received as parameters, so that your

39
00:03:21,600 --> 00:03:26,420
functions are as predictable and reusable as possible.

40
00:03:26,520 --> 00:03:32,580
So for this connect form function, this means that we would probably get the form ID as a parameter

41
00:03:32,820 --> 00:03:39,310
and also the form submit handler function as a parameter

42
00:03:39,540 --> 00:03:46,860
and then here instead of pointing at user input here, we would point at form ID and here we would just

43
00:03:46,860 --> 00:03:48,810
say form submit handler

44
00:03:48,810 --> 00:03:54,990
and now this function has code which is totally reusable, which makes no assumptions about what's in

45
00:03:54,990 --> 00:03:56,250
your HTML file,

46
00:03:56,280 --> 00:04:02,200
it makes no assumption about this ID and about the name of the function that should handle the submission.

47
00:04:02,280 --> 00:04:06,120
Instead we would call connect form here when our app is initialized,

48
00:04:06,120 --> 00:04:10,870
so when this Javascript file is passed and executed for the first time

49
00:04:10,920 --> 00:04:17,640
and here I would feed in the concrete values, so user input and a pointer at signupHandler.

50
00:04:17,700 --> 00:04:23,280
Now of course in this simple app we don't gain much by this but now we really have a function which

51
00:04:23,280 --> 00:04:29,970
is pretty focused, pretty straightforward, pretty easy to understand and which is also pretty reusable

52
00:04:30,030 --> 00:04:34,420
because it's not tied to a specific form in the HTML code.

53
00:04:34,440 --> 00:04:39,600
If we had multiple forms which we wanted to connect with submit handlers, we could reuse this function

54
00:04:39,810 --> 00:04:45,560
and we could just call it with different arguments, that already is how you should think about code

55
00:04:45,690 --> 00:04:50,240
when thinking in a functional programming style.

56
00:04:50,370 --> 00:04:55,860
So now we connect this form, we point at the signupHandler when the form gets submitted. In the sign

57
00:04:55,860 --> 00:04:56,820
up handler,

58
00:04:56,820 --> 00:05:03,960
we now want to get our user input and we now also of course then want to validate it and create a new

59
00:05:03,960 --> 00:05:05,260
user.

60
00:05:05,280 --> 00:05:08,460
Now again we could copy our logic from procedural right,

61
00:05:08,460 --> 00:05:14,610
we could copy this logic here for getting the user input for the moment and paste it in here and this

62
00:05:14,610 --> 00:05:19,220
would work but we're not really thinking in a functional way.

63
00:05:19,230 --> 00:05:21,650
What did I just say about functions?

64
00:05:21,840 --> 00:05:28,440
Well they should be pure and should receive all the inputs they need as parameters

65
00:05:28,440 --> 00:05:34,410
and here again I'm hardcoding IDs which are IDs for my HTML document into the function.

66
00:05:34,410 --> 00:05:37,230
Now we could do this but is this good?

67
00:05:37,230 --> 00:05:38,880
Well it's certainly not bad.

68
00:05:38,910 --> 00:05:44,070
Now you might argue that hardcoding these IDs into the function is not something you want to do because

69
00:05:44,070 --> 00:05:49,530
we got rid of it here but I would argue that the signupHandler is of course a very specific function

70
00:05:49,530 --> 00:05:55,200
which indeed can be tied to the HTML file because it really is about this sign up form.

71
00:05:55,290 --> 00:06:00,470
It's not a general function here, like connect form was which should work with any form,

72
00:06:00,480 --> 00:06:07,080
this way you should only work with the signing up logic so that is fine but we're basically having some

73
00:06:07,080 --> 00:06:08,910
code repetition here.

74
00:06:09,090 --> 00:06:16,150
Why don't we create a new function here which we name get user input

75
00:06:16,320 --> 00:06:22,830
and here I expect to get my input element ID

76
00:06:23,130 --> 00:06:29,550
and in this function we then return document get element by ID to which I forward the input element ID

77
00:06:29,740 --> 00:06:33,840
parameter and then I access .value here.

78
00:06:33,850 --> 00:06:37,650
Now of course, this only works with the input elements but that's the idea behind this function,

79
00:06:37,660 --> 00:06:42,970
so we could add an extra check which checks if this is an HTML input element

80
00:06:42,970 --> 00:06:45,560
but here I just assume that it always will be one

81
00:06:45,700 --> 00:06:47,400
and now we can rewrite this.

82
00:06:47,560 --> 00:06:50,700
We can get rid of this line here and entered username

83
00:06:50,700 --> 00:07:00,550
now simply is get user input for the username ID and we can get rid of this line and the entered password

84
00:07:00,600 --> 00:07:05,220
now just is get user input for password

85
00:07:05,460 --> 00:07:07,730
and again we have a reusable function here

86
00:07:07,800 --> 00:07:12,520
and this is now leaner and more focused. So now we get the input,

87
00:07:12,620 --> 00:07:19,130
of course we want to validate it. So unsurprisingly we create a new function for this, the validate

88
00:07:19,340 --> 00:07:20,650
function

89
00:07:20,690 --> 00:07:25,280
and here we could again follow the logic we set up into object oriented part.

90
00:07:25,460 --> 00:07:34,260
We can expect a value, a flag and a validator value here and then basically copy over to logic from oop

91
00:07:34,280 --> 00:07:41,470
because object oriented programming and functional program is not that far apart.

92
00:07:41,540 --> 00:07:45,450
It's a bit more than just translating classes to functions

93
00:07:45,560 --> 00:07:52,700
but the idea of organizing logic in methods and in classes is not that far away from the idea of organizing

94
00:07:52,700 --> 00:07:54,190
logic and functions.

95
00:07:54,230 --> 00:08:00,170
So unsurprisingly, we can copy the logic from the validate method here and add it in the validate function

96
00:08:00,170 --> 00:08:01,700
here.

97
00:08:01,720 --> 00:08:07,390
Now we just need to replace this required and this min length with just required and min length and add

98
00:08:07,390 --> 00:08:09,180
some global constants here

99
00:08:09,280 --> 00:08:10,980
and yes this is also possible,

100
00:08:11,050 --> 00:08:14,810
not everything has to be inside of a function.

101
00:08:14,920 --> 00:08:22,120
Here we want some global flags, some global identifiers and therefore we can define them just like this

102
00:08:22,210 --> 00:08:23,770
in our script here.

103
00:08:23,770 --> 00:08:29,450
So now we have that, we have our validate function and we can now use this validate function here in

104
00:08:29,440 --> 00:08:30,550
the signupHandler.

105
00:08:31,150 --> 00:08:37,510
So here we could now call validate and forward the entered username and so on and that again would

106
00:08:37,510 --> 00:08:48,330
not be wrong but I want to create yet another new function, maybe here which I'll name create user and

107
00:08:48,330 --> 00:08:53,830
this is a function that takes the username and the user password

108
00:08:54,030 --> 00:08:56,100
and this should now run the validation

109
00:08:56,190 --> 00:09:00,730
and that's just of course one way of doing it, not the only correct one, just one way of doing it.

110
00:09:00,750 --> 00:09:09,480
So I want to run validation here and then if it succeeds, also create my user. So in here, I will now check

111
00:09:09,570 --> 00:09:15,000
if not validate for username and the required flag,

112
00:09:15,000 --> 00:09:24,930
so if this yields false or if validate for the user password and the min length flag and a min length of

113
00:09:24,930 --> 00:09:27,510
five, if either of the two yields false,

114
00:09:27,660 --> 00:09:31,020
we could throw an alert but this would be a side effect.

115
00:09:31,020 --> 00:09:38,130
Now what's the side effect? A side effect basically is some logic you execute inside of a function which

116
00:09:38,460 --> 00:09:44,850
does something outside of the function, which sends an HttpRequest, which changes something in

117
00:09:44,850 --> 00:09:48,000
the DOM or like in this case, which shows an alert,

118
00:09:48,030 --> 00:09:50,010
so these are typical side effects.

119
00:09:50,100 --> 00:09:56,190
A pure function just receives parameters and then maybe returns something and for the same parameters,

120
00:09:56,250 --> 00:10:02,850
it always returns the same thing. An impure function which has a side effect might also do that,

121
00:10:02,850 --> 00:10:09,010
it might also return always the same thing but it also might manipulate something outside of the function,

122
00:10:09,000 --> 00:10:15,720
so like I said in the DOM or send a HttpRequest. Now sometimes you can't avoid this but here,

123
00:10:15,750 --> 00:10:20,140
I want to have create user as a pure function, so I will not throw my alert here,

124
00:10:20,190 --> 00:10:27,100
instead I will throw a new error here with an error message of invalid input and I'll just copy the

125
00:10:27,570 --> 00:10:30,980
error message from the oop file here.

126
00:10:31,060 --> 00:10:37,720
So copy that string and throw this here as an error message on this Javascript error.

127
00:10:37,720 --> 00:10:39,280
So here we're not showing an alert,

128
00:10:39,280 --> 00:10:45,040
we're really throwing an error and that will automatically cancel the execution of the remaining function.

129
00:10:45,670 --> 00:10:47,650
If this error gets not thrown,

130
00:10:47,650 --> 00:10:54,970
so if we make it past this if check, if we do have valid inputs, then I will return a new object and that

131
00:10:54,970 --> 00:11:01,360
is my user with a username which holds the username value and with a password which holds this user

132
00:11:01,360 --> 00:11:03,200
password value.

133
00:11:03,280 --> 00:11:07,710
So now create user is something we could call here in the signupHandler,

134
00:11:07,720 --> 00:11:17,500
and we got our new user by calling create user and we forward the entered username and the entered password.

135
00:11:17,510 --> 00:11:18,650
Now this could fail

136
00:11:18,650 --> 00:11:23,120
however, this would throw an error if we have invalid inputs.

137
00:11:23,120 --> 00:11:29,690
So here we can use try catch and again we could use try catch in the object oriented style and in the procedural

138
00:11:29,690 --> 00:11:30,770
style as well,

139
00:11:30,770 --> 00:11:35,570
don't get me wrong but now I think here is really clean to do it like this.

140
00:11:35,570 --> 00:11:41,720
We use try catch and we try to create a new user but if this fails, I will now show my alert here and

141
00:11:41,720 --> 00:11:48,710
yes this will now produce a side effect but we could even outsource this into a separate function, show

142
00:11:48,980 --> 00:11:49,640
alert

143
00:11:49,670 --> 00:11:54,530
but since I would do nothing else in there but call the alert function, I'll do it just in here.

144
00:11:54,530 --> 00:11:56,540
And as I said, sometimes you can't avoid it,

145
00:11:56,540 --> 00:11:59,900
it's okay to have functions that produce side effects,

146
00:11:59,900 --> 00:12:04,140
you just want to keep most functions pure and side effect free,

147
00:12:04,280 --> 00:12:08,400
here however I will output the error message in an alert.

148
00:12:08,810 --> 00:12:13,150
If this succeeds however, I want to console log the new user

149
00:12:13,250 --> 00:12:20,010
and of course also greet the new user and for that we could create a new function here,

150
00:12:20,150 --> 00:12:28,300
the greet user function which gets a user object and just calls console log

151
00:12:28,310 --> 00:12:39,650
Hi I am plus user username and again, this here would also technically be a side effect by the way because

152
00:12:39,650 --> 00:12:41,960
we do something outside of the function.

153
00:12:41,960 --> 00:12:46,490
So here I can then call greet user and forward the new user

154
00:12:46,490 --> 00:12:48,610
and there are different ways of writing this,

155
00:12:48,620 --> 00:12:56,340
these are just examples of course. If we now save this and we reload this page, if the form is empty and

156
00:12:56,340 --> 00:12:57,020
I click submit,

157
00:12:57,030 --> 00:13:01,860
I get this error. If I have a valid username but my password is too short,

158
00:13:01,860 --> 00:13:09,250
I get an error. If my password is long enough but the username is empty,

159
00:13:09,250 --> 00:13:16,320
I get an error and if both is valid and we click create user, we're showing Hi

160
00:13:16,320 --> 00:13:20,590
I am Maximilian, the log is missing because I didn't enter it here,

161
00:13:20,590 --> 00:13:25,980
so here of course I want to log my new user and then retry this, so reload,

162
00:13:29,440 --> 00:13:31,410
enter the values here again

163
00:13:31,640 --> 00:13:33,840
and now we get the same output as before.

164
00:13:34,430 --> 00:13:36,580
So this now really is working

165
00:13:36,590 --> 00:13:40,340
and now this is an example of functional programming.

166
00:13:40,340 --> 00:13:46,910
The core idea of course being that we organize our code into functions where most functions are pure

167
00:13:47,240 --> 00:13:50,420
and side effect free and therefore, highly reusable.
