1
00:00:00,000 --> 00:00:08,095
Now that we have completed updating the server-side,

2
00:00:08,095 --> 00:00:10,770
it's time to move on to the Angular Client.

3
00:00:10,770 --> 00:00:13,830
For your convenience, I have provided you with

4
00:00:13,830 --> 00:00:17,700
the GitHub repository that contains the final version of

5
00:00:17,700 --> 00:00:20,840
the Angular Client that is able to communicate with

6
00:00:20,840 --> 00:00:26,805
our REST API Server and then render the various views for our client.

7
00:00:26,805 --> 00:00:29,690
So, I have taken the Angular application that we

8
00:00:29,690 --> 00:00:32,895
developed in the second course of this specialization,

9
00:00:32,895 --> 00:00:34,380
and then modified it.

10
00:00:34,380 --> 00:00:39,680
We will take a brief tour through the code in a little bit later.

11
00:00:39,680 --> 00:00:44,005
Now, you will clone the Git repository to your computer,

12
00:00:44,005 --> 00:00:47,525
and then start-up your Angular Client,

13
00:00:47,525 --> 00:00:50,820
and then see it communicating with our server-side.

14
00:00:50,820 --> 00:00:54,555
Let's see the details next.

15
00:00:54,555 --> 00:00:57,885
To get started with this exercise,

16
00:00:57,885 --> 00:01:01,345
at your terminal or command window,

17
00:01:01,345 --> 00:01:04,070
go to your convenient location and then at

18
00:01:04,070 --> 00:01:06,685
the prompt type git clone

19
00:01:06,685 --> 00:01:21,615
https://github.com/jmuppala/conFusion-Angular6.git.

20
00:01:21,615 --> 00:01:28,705
Then, let the Angular application be cloned to your computer.

21
00:01:28,705 --> 00:01:30,495
Once the cloning is complete,

22
00:01:30,495 --> 00:01:39,340
move to the conFusion-Angular6 folder

23
00:01:39,340 --> 00:01:43,620
that has just been created when you clone this git repository.

24
00:01:43,620 --> 00:01:48,845
Then you will immediately notice that there are a bunch of files already there.

25
00:01:48,845 --> 00:01:56,700
Now, at the prompt, type npm install,

26
00:01:56,700 --> 00:02:00,500
in order to install all the node modules on

27
00:02:00,500 --> 00:02:04,460
which this Angular application is dependent upon.

28
00:02:04,460 --> 00:02:09,415
So, once the node modules or all installed,

29
00:02:09,415 --> 00:02:18,095
then we can start up our NG serve to compile and serve up our Angular application.

30
00:02:18,095 --> 00:02:21,765
Once everything is installed by npm install,

31
00:02:21,765 --> 00:02:27,080
then make sure that your MongoDB Server is up

32
00:02:27,080 --> 00:02:32,365
and running and also your REST API Server is also up and running.

33
00:02:32,365 --> 00:02:35,165
Otherwise, your Angular Client will not work.

34
00:02:35,165 --> 00:02:39,720
So, now that you have installed your Angular Client on your computer,

35
00:02:39,720 --> 00:02:43,815
at the prompt type ng serve and

36
00:02:43,815 --> 00:02:50,755
your Angular application will be compiled and served up by ng serve in a short while.

37
00:02:50,755 --> 00:02:54,725
Once your Angular application is successfully compiled,

38
00:02:54,725 --> 00:02:59,345
then go to a browser and open your Angular application in the browser.

39
00:02:59,345 --> 00:03:01,025
Going to the browser,

40
00:03:01,025 --> 00:03:06,665
at the address bar,

41
00:03:06,665 --> 00:03:12,050
let me type in localhost:4200 and

42
00:03:12,050 --> 00:03:14,345
you will see that your Angular application gets

43
00:03:14,345 --> 00:03:17,930
started up and is visible on the screen here.

44
00:03:17,930 --> 00:03:21,170
You will notice immediately that your Angular application

45
00:03:21,170 --> 00:03:24,500
is able to fetch the data from the server and then render

46
00:03:24,500 --> 00:03:28,115
the various parts of your Angular application just like what you

47
00:03:28,115 --> 00:03:33,040
did at the end of your Angular course.

48
00:03:33,080 --> 00:03:35,605
When you go to talk about folder,

49
00:03:35,605 --> 00:03:42,730
you will also see that the About page also renders the information as such.

50
00:03:42,730 --> 00:03:45,970
In the menu, you see the items in the menu being

51
00:03:45,970 --> 00:03:49,475
displayed just like we saw with the Angular application.

52
00:03:49,475 --> 00:03:51,595
Now, in addition, I have added in

53
00:03:51,595 --> 00:03:56,320
one more page to the single page application called My Favorites,

54
00:03:56,320 --> 00:04:02,590
which you cannot navigate to because no user is logged into the system.

55
00:04:02,590 --> 00:04:05,960
So, you see that I don't have any user logged into the system.

56
00:04:05,960 --> 00:04:09,120
So, that's why there's no point in indicating my favorites,

57
00:04:09,120 --> 00:04:10,845
because you don't know which user,

58
00:04:10,845 --> 00:04:12,990
as favorites, should be shown here.

59
00:04:12,990 --> 00:04:15,580
The contact page as usual.

60
00:04:15,580 --> 00:04:17,345
Now, let's login.

61
00:04:17,345 --> 00:04:19,235
To login to our application,

62
00:04:19,235 --> 00:04:25,665
we'll click on the Login button and then you would see that the Login dialog pops up.

63
00:04:25,665 --> 00:04:32,620
Then, let me login as one of the registered users,

64
00:04:32,620 --> 00:04:37,295
which we registered as part of this course earlier.

65
00:04:37,295 --> 00:04:39,100
So, once you login,

66
00:04:39,100 --> 00:04:41,840
you will immediately notice that,

67
00:04:41,840 --> 00:04:44,150
to the right corner,

68
00:04:44,150 --> 00:04:47,410
you see the Login button has now turned into

69
00:04:47,410 --> 00:04:51,730
Logout and the User's name is indicated here.

70
00:04:51,730 --> 00:04:54,500
So, whoever is logged in is indicated here.

71
00:04:54,500 --> 00:04:56,110
You could also, in principle,

72
00:04:56,110 --> 00:05:00,925
replace this with the image of the user.

73
00:05:00,925 --> 00:05:03,715
Now, for that you need to do more modifications to

74
00:05:03,715 --> 00:05:07,790
both the client and the server in order to support the image display here.

75
00:05:07,790 --> 00:05:10,570
But, at the moment, I'm just showing you how we

76
00:05:10,570 --> 00:05:14,260
can easily display the user information here.

77
00:05:14,260 --> 00:05:17,200
So, this require minor modification to the head of

78
00:05:17,200 --> 00:05:20,335
component where I will be able to retrieve

79
00:05:20,335 --> 00:05:23,410
the username from a service

80
00:05:23,410 --> 00:05:27,060
called as the OAuth service which we will talk about in a short while.

81
00:05:27,060 --> 00:05:29,420
So, once the user logs in,

82
00:05:29,420 --> 00:05:31,955
then if you now click on My Favorites,

83
00:05:31,955 --> 00:05:35,360
you would notice that there is nothing in my favorites for the user.

84
00:05:35,360 --> 00:05:40,815
Obviously, because the user has not yet chosen any favorites.

85
00:05:40,815 --> 00:05:44,675
So, let's now go to the Menu and then in the Menu,

86
00:05:44,675 --> 00:05:52,980
let me select one item and then they will add this dish to our favorites.

87
00:05:52,980 --> 00:05:55,230
So, going down below here,

88
00:05:55,230 --> 00:05:58,415
you see the heart symbol there,

89
00:05:58,415 --> 00:06:02,655
click on that and you'll see that this would be added into The Favorites.

90
00:06:02,655 --> 00:06:06,620
The fact that this has been added into The Favorites is indicated by

91
00:06:06,620 --> 00:06:12,790
the change in the icon here from a unfilled heart to a filled heart.

92
00:06:12,790 --> 00:06:15,790
Now, if you go to any other dish,

93
00:06:15,790 --> 00:06:19,080
you would notice that this has an unfilled heart,

94
00:06:19,080 --> 00:06:22,795
which means that this is not yet among our favorites.

95
00:06:22,795 --> 00:06:25,070
So, let me add in one more item to

96
00:06:25,070 --> 00:06:29,990
my favorites and then let's add a third item to my favorites also.

97
00:06:29,990 --> 00:06:37,455
So, now, you will see that if I now go to My Favorites,

98
00:06:37,455 --> 00:06:42,560
you will see a set of My Favorites being displayed here.

99
00:06:42,560 --> 00:06:46,610
So, you saw that I just added these three dishes to My Favorites.

100
00:06:46,610 --> 00:06:48,820
So, these are being displayed here.

101
00:06:48,820 --> 00:06:57,100
So, this is tracked by using the favorites end point on the server-side,

102
00:06:57,100 --> 00:06:59,870
which I've implemented as part of your last assignment.

103
00:06:59,870 --> 00:07:05,554
So, if you have done that assignment correctly then this part should work as expected.

104
00:07:05,554 --> 00:07:09,310
Now, we can also modify My Favorite.

105
00:07:09,310 --> 00:07:11,320
So, for example, at the right corner here,

106
00:07:11,320 --> 00:07:14,165
you see this Delete toggle here.

107
00:07:14,165 --> 00:07:16,320
So, let me turn that on.

108
00:07:16,320 --> 00:07:17,730
So, when you turn it on,

109
00:07:17,730 --> 00:07:22,025
you immediately see the three red crosses

110
00:07:22,025 --> 00:07:27,630
appear at the bottom of these three items in My Favorites.

111
00:07:27,630 --> 00:07:29,905
When I click it off, then they disappear.

112
00:07:29,905 --> 00:07:36,750
So, this is one way of turning on the delete buttons on your My Favorites and then.

113
00:07:36,750 --> 00:07:40,965
So, let me go ahead and delete one of the items from My Favorites.

114
00:07:40,965 --> 00:07:42,515
So, when I click on that button,

115
00:07:42,515 --> 00:07:47,540
you'll notice immediately that that item is deleted from My Favorites,

116
00:07:47,540 --> 00:07:50,405
and immediately disappears and My Favorites gets

117
00:07:50,405 --> 00:07:54,780
updated and you'll see the resulting value being shown here.

118
00:07:54,780 --> 00:07:56,115
At the same time,

119
00:07:56,115 --> 00:07:58,530
this Delete toggle is turned off,

120
00:07:58,530 --> 00:08:01,250
so that the delete buttons are no longer visible.

121
00:08:01,250 --> 00:08:07,610
I can always again turn on the delete buttons by clicking on the on and off here.

122
00:08:07,610 --> 00:08:11,210
So, notice that the My Favorites will be displayed only

123
00:08:11,210 --> 00:08:15,790
for users that are logged in to the system.

124
00:08:15,790 --> 00:08:21,260
So, you immediately notice a set of changes that have been

125
00:08:21,260 --> 00:08:23,540
done to the Angular Client in order to

126
00:08:23,540 --> 00:08:26,930
support some of these additional features that you see here.

127
00:08:26,930 --> 00:08:31,190
You also saw the Login and Logout feature being supported here.

128
00:08:31,190 --> 00:08:33,000
So, when I click on the Logout button,

129
00:08:33,000 --> 00:08:35,930
you immediately notice that the user gets logged out

130
00:08:35,930 --> 00:08:39,800
and the username disappears from there,

131
00:08:39,800 --> 00:08:44,250
and so the button also is turned into the Login button.

132
00:08:44,560 --> 00:08:49,760
So, with this, you notice how my Angular client has been

133
00:08:49,760 --> 00:08:54,880
updated to make use of the new REST API server

134
00:08:54,880 --> 00:08:59,100
in order to support the favorites being saved and on the server side and

135
00:08:59,100 --> 00:09:04,930
then automatically being reflected into my client application as shown here.

136
00:09:04,930 --> 00:09:08,305
Let's take a brief tour through

137
00:09:08,305 --> 00:09:14,160
the Angular code that I have supplied for you in the GitHub repository,

138
00:09:14,160 --> 00:09:17,710
and also see how we have modified parts of the code in

139
00:09:17,710 --> 00:09:21,655
order to implement the updated Angular application.

140
00:09:21,655 --> 00:09:24,310
You will notice that there is a new service

141
00:09:24,310 --> 00:09:27,130
that I have introduced here called auth service.

142
00:09:27,130 --> 00:09:29,295
The auth service takes care of

143
00:09:29,295 --> 00:09:35,985
all the authentication-related actions for the Angular application.

144
00:09:35,985 --> 00:09:37,715
So, within the auth service,

145
00:09:37,715 --> 00:09:40,760
you would immediately notice that I have

146
00:09:40,760 --> 00:09:45,545
a set of information that I have configured here.

147
00:09:45,545 --> 00:09:47,985
Since you already know Angular,

148
00:09:47,985 --> 00:09:52,535
you should be able to easily process whatever is written here.

149
00:09:52,535 --> 00:09:57,355
Note in particular that within the auth service itself,

150
00:09:57,355 --> 00:09:59,240
I am storing information like,

151
00:09:59,240 --> 00:10:00,815
for example, the tokenKey,

152
00:10:00,815 --> 00:10:06,985
which is the key for the local storage where I am storing the JSON Web Token,

153
00:10:06,985 --> 00:10:11,500
and also some additional variables

154
00:10:11,500 --> 00:10:16,310
here where I am tracking the user name and where I am authenticated,

155
00:10:16,310 --> 00:10:21,955
and also keep track of the the JSON Web Token here.

156
00:10:21,955 --> 00:10:28,540
Now, let's begin by looking at when the user logs in.

157
00:10:28,540 --> 00:10:30,290
So, when the user logs in,

158
00:10:30,290 --> 00:10:37,135
then this function called the login will be called in our auth service here,

159
00:10:37,135 --> 00:10:40,350
and when the login is called in the auth service,

160
00:10:40,350 --> 00:10:44,730
this will be passed in a parameter called user which contains

161
00:10:44,730 --> 00:10:49,665
the username and password as part of the user JavaScript object.

162
00:10:49,665 --> 00:10:57,890
So, at this point, I am doing an HTTP post to the baseURL plus users/login.

163
00:10:57,890 --> 00:11:00,320
Note also that here,

164
00:11:00,320 --> 00:11:06,030
I am supplying the AuthResponse as the qualifier here.

165
00:11:06,030 --> 00:11:09,945
The AuthResponse is nothing but an interface that I have implemented here,

166
00:11:09,945 --> 00:11:11,350
at the top here.

167
00:11:11,350 --> 00:11:14,295
So, this interface essentially specifies

168
00:11:14,295 --> 00:11:16,860
the information that is going to come back as

169
00:11:16,860 --> 00:11:19,670
my authentication response from the server side,

170
00:11:19,670 --> 00:11:22,690
the structure of the JSON data that is coming

171
00:11:22,690 --> 00:11:25,690
back from the server side and the corresponding JavaScript objects.

172
00:11:25,690 --> 00:11:28,865
So, you notice that when we updated the server,

173
00:11:28,865 --> 00:11:32,370
we made sure that the server is sending back the status,

174
00:11:32,370 --> 00:11:37,035
the success, flag, and the token in the string index.

175
00:11:37,035 --> 00:11:42,000
So, that information is obtained in here.

176
00:11:42,000 --> 00:11:44,240
Now, when I am doing a post on that,

177
00:11:44,240 --> 00:11:52,975
I am passing in the username and password to the post on this /users/login endpoint.

178
00:11:52,975 --> 00:11:58,375
When the reply comes back from the response,

179
00:11:58,375 --> 00:12:03,490
the response message itself will contain, as we saw,

180
00:12:03,490 --> 00:12:06,525
the success, the token field,

181
00:12:06,525 --> 00:12:09,885
and also the status message here.

182
00:12:09,885 --> 00:12:11,950
So, from the response message,

183
00:12:11,950 --> 00:12:16,960
I'm extracting the token and then passing it in to this function which I implement here,

184
00:12:16,960 --> 00:12:20,415
local function here, called storeUserCredentials.

185
00:12:20,415 --> 00:12:30,295
So, that will be returned to my application and will be stored in my client side,

186
00:12:30,295 --> 00:12:32,220
into the local storage.

187
00:12:32,220 --> 00:12:34,545
Then, from this function,

188
00:12:34,545 --> 00:12:37,870
I am returning this information back to

189
00:12:37,870 --> 00:12:43,160
the calling function from where I initiated the login process.

190
00:12:43,160 --> 00:12:51,610
So, this way, I will be indicating to my login component that the login was successful,

191
00:12:51,610 --> 00:12:56,345
and then I will also pass in the username to my login component,

192
00:12:56,345 --> 00:12:59,680
which then will pass that information onto the header component,

193
00:12:59,680 --> 00:13:03,860
and the header component uses that to reflect the username onto

194
00:13:03,860 --> 00:13:08,830
the toolbar at the top there,

195
00:13:08,830 --> 00:13:11,145
and also we catch the error here.

196
00:13:11,145 --> 00:13:16,390
So, this is a very simple implementation of how we performed the login.

197
00:13:16,390 --> 00:13:17,840
When you do the logout,

198
00:13:17,840 --> 00:13:20,735
notice what I do when the user calls a logout.

199
00:13:20,735 --> 00:13:22,070
When the user calls a logout,

200
00:13:22,070 --> 00:13:24,560
I just simply destroy the user's credentials,

201
00:13:24,560 --> 00:13:26,845
which includes throwing away

202
00:13:26,845 --> 00:13:33,085
the JSON Web Token that I have obtained when I logged into my application.

203
00:13:33,085 --> 00:13:37,010
Then, some additional helper functions that I have implemented here called

204
00:13:37,010 --> 00:13:40,920
getUsername is logged in and getToken,

205
00:13:40,920 --> 00:13:45,370
which will be useful from my other applications,

206
00:13:45,370 --> 00:13:50,140
other components and services.

207
00:13:50,140 --> 00:13:57,375
So, now let's look at some of the helper functions that we have implemented here.

208
00:13:57,375 --> 00:14:04,685
So, the loadUserCredentials will retrieve the credentials from the local storage.

209
00:14:04,685 --> 00:14:10,800
So, you notice that here I am calling localStorage and then saying getItem.

210
00:14:10,800 --> 00:14:12,750
So, the localStorage here is using

211
00:14:12,750 --> 00:14:17,305
the web browser's local storage that is supported by standard web browsers,

212
00:14:17,305 --> 00:14:19,140
and storing the information there,

213
00:14:19,140 --> 00:14:21,620
and then it is retrieving this information there.

214
00:14:21,620 --> 00:14:23,830
Then, from there, the credential information,

215
00:14:23,830 --> 00:14:25,745
if it is valid,

216
00:14:25,745 --> 00:14:27,950
then those credentials will be set up here.

217
00:14:27,950 --> 00:14:32,735
So, all these variables that I have defined here will be initialized with

218
00:14:32,735 --> 00:14:38,965
the appropriate information after being retrieved from the localStorage.

219
00:14:38,965 --> 00:14:42,560
Now, similarly, the storeUserCredentials function

220
00:14:42,560 --> 00:14:46,285
that I've implemented here is called from the login method.

221
00:14:46,285 --> 00:14:50,165
When this information is passed in,

222
00:14:50,165 --> 00:14:52,290
the credential information is passed in,

223
00:14:52,290 --> 00:14:57,665
that information is stored in the localStorage at this point with that key.

224
00:14:57,665 --> 00:15:00,825
Then, the useCredentials basically

225
00:15:00,825 --> 00:15:05,510
sets up all the variables that I have in the auth service.

226
00:15:05,510 --> 00:15:07,285
So, it sets up the token,

227
00:15:07,285 --> 00:15:09,225
it sets up the username,

228
00:15:09,225 --> 00:15:14,270
and then it sets up the isAuthenticated function here.

229
00:15:14,270 --> 00:15:17,590
So, notice that the username itself here,

230
00:15:17,590 --> 00:15:20,865
I have declared it as a subject,

231
00:15:20,865 --> 00:15:23,595
which is nothing but an observable here.

232
00:15:23,595 --> 00:15:27,410
So, that is why whenever I say,

233
00:15:27,410 --> 00:15:30,705
sendUsername here, I say credentials username.

234
00:15:30,705 --> 00:15:34,780
So, this sendUsername implemented right at the top here,

235
00:15:34,780 --> 00:15:40,080
notice that this is where the observable value is sent back.

236
00:15:40,080 --> 00:15:43,305
So, that's why I'm saying this username next.

237
00:15:43,305 --> 00:15:45,370
So, the observable.

238
00:15:45,370 --> 00:15:49,630
Will send back the name that is supplied as

239
00:15:49,630 --> 00:15:55,130
a parameter to whoever has registered themselves to observe this observable.

240
00:15:55,130 --> 00:15:59,070
So this observable, I'm going to be observing this from

241
00:15:59,070 --> 00:16:03,980
my header component and so that way whenever the username changes,

242
00:16:03,980 --> 00:16:09,870
either from undefined to a given username or vice versa,

243
00:16:09,870 --> 00:16:13,040
then I can update my toolbar in

244
00:16:13,040 --> 00:16:17,670
the header component to reflect whether the user is logged in or logged out.

245
00:16:17,670 --> 00:16:21,770
So that is set up by using this useCredentials.

246
00:16:21,770 --> 00:16:29,010
Now the destroyUserCredentials basically sets the authentication token to undefined.

247
00:16:29,010 --> 00:16:34,320
It clears the username and then sets the IsAuthenticated to false and then

248
00:16:34,320 --> 00:16:37,560
removes this information from my local store it so

249
00:16:37,560 --> 00:16:40,930
it's basically throwing away the jsonwebtoken at this part.

250
00:16:40,930 --> 00:16:43,330
So that is how you love out a user.

251
00:16:43,330 --> 00:16:47,150
So once the jsonwebtoken is lost the user can no longer

252
00:16:47,150 --> 00:16:49,850
authenticate himself or herself on

253
00:16:49,850 --> 00:16:53,305
the server side because the token is no longer available to us.

254
00:16:53,305 --> 00:16:58,340
So that's how we implement the logout function within our application.

255
00:16:58,340 --> 00:17:01,030
So take some time to go through the

256
00:17:01,030 --> 00:17:05,350
auth.service here to see how I have implemented the various functionality.

257
00:17:05,350 --> 00:17:06,865
Now, by this time,

258
00:17:06,865 --> 00:17:13,190
I am sure you are very familiar with how Angular applications are implemented,

259
00:17:13,190 --> 00:17:17,960
so it should not be that difficult for you to understand how this code is implemented.

260
00:17:17,960 --> 00:17:24,575
Now one more function that I would draw your attention to is the check JWT token, here.

261
00:17:24,575 --> 00:17:29,040
This function can be called at any point to check and make

262
00:17:29,040 --> 00:17:33,360
sure that our JSON web token is still valid.

263
00:17:33,360 --> 00:17:40,500
So this is where I am sending the get request to users slash check JWT token.

264
00:17:40,500 --> 00:17:49,450
Recall that we implemented this route on the server side in the user's.js and.

265
00:17:49,450 --> 00:17:55,385
So from there we will be able to verify whether the jsonwebtoken is still valid or not.

266
00:17:55,385 --> 00:17:57,855
If the jsonwebtoken is not valid,

267
00:17:57,855 --> 00:17:59,170
then we're going to destroy

268
00:17:59,170 --> 00:18:03,045
the user's credentials and then expect the user to log in again.

269
00:18:03,045 --> 00:18:06,550
If the jsonwebtoken is valid then it's okay and

270
00:18:06,550 --> 00:18:10,375
we can proceed forward with allowing the user to

271
00:18:10,375 --> 00:18:14,540
to recognize that we are logged in.So even if you close

272
00:18:14,540 --> 00:18:18,665
your browser and then reopened the browser and then reopened your Angular application,

273
00:18:18,665 --> 00:18:26,625
if you had logged in earlier and the jsonwebtoken was saved into the local storage,

274
00:18:26,625 --> 00:18:28,930
it can be retrieved from there and then

275
00:18:28,930 --> 00:18:33,740
your login status will be restored within your Angular application.

276
00:18:33,740 --> 00:18:36,420
If the json web token is expired,

277
00:18:36,420 --> 00:18:38,635
then we will not be allowed to log in.

278
00:18:38,635 --> 00:18:44,280
So every time you refresh your Angular application in your browser or

279
00:18:44,280 --> 00:18:47,290
reload your Angular application in your browser you're going to be

280
00:18:47,290 --> 00:18:50,550
checking the jsonwebtoken to make sure that it is still valid.

281
00:18:50,550 --> 00:18:53,095
If it is not valid then the user will be

282
00:18:53,095 --> 00:18:56,200
cleared out and so you will have to log in again.

283
00:18:56,200 --> 00:19:00,370
If not, then the logged in user's information is retrieved

284
00:19:00,370 --> 00:19:05,020
from the localStorage and then initialized within my Angular application.

285
00:19:05,020 --> 00:19:09,765
Periodically, if at any point in time your server

286
00:19:09,765 --> 00:19:15,575
responds with a 401 Unauthorized message,

287
00:19:15,575 --> 00:19:16,880
even at that point,

288
00:19:16,880 --> 00:19:22,045
we will again crosscheck to see that the jsonwebtoken is valid and then allow that.

289
00:19:22,045 --> 00:19:26,960
We will do that using something called the Http interceptors.

290
00:19:26,960 --> 00:19:30,630
Let me take a tour to that part of the code,

291
00:19:30,630 --> 00:19:35,180
and then explain to you how the interceptors work in a short while.

292
00:19:35,180 --> 00:19:38,635
So now in addition to authService,

293
00:19:38,635 --> 00:19:45,545
in the services folder itself you will see this file called authInterceptors.ts file.

294
00:19:45,545 --> 00:19:51,285
So open this and you will see that here I have implemented Http interceptors.

295
00:19:51,285 --> 00:19:54,435
Now what this Http interceptors do,

296
00:19:54,435 --> 00:20:00,780
this is supported with the Http client which comes as part of Angular 4.4.

297
00:20:00,780 --> 00:20:04,080
What the http interceptors do is they can intercept

298
00:20:04,080 --> 00:20:06,180
outgoing requests messages make

299
00:20:06,180 --> 00:20:09,695
modifications to the request message before it is sent out.

300
00:20:09,695 --> 00:20:13,530
Similarly, they can intercept incoming response messages and then modify

301
00:20:13,530 --> 00:20:15,660
the incoming response message before

302
00:20:15,660 --> 00:20:18,970
the response is handed over to the Angular application.

303
00:20:18,970 --> 00:20:22,920
So through interception, so how does this interceptor work?

304
00:20:22,920 --> 00:20:25,625
So to make this interceptor work,

305
00:20:25,625 --> 00:20:28,620
we implement, as you see,

306
00:20:28,620 --> 00:20:37,285
a class called as an HttpInterceptor by extending the HttpInterceptor.

307
00:20:37,285 --> 00:20:39,805
So here I have implemented the AuthInterceptor.

308
00:20:39,805 --> 00:20:42,175
So what does this AuthInterceptor do?

309
00:20:42,175 --> 00:20:47,660
This AuthInterceptor is basically capturing outgoing requests.

310
00:20:47,660 --> 00:20:51,785
So to capture an outgoing request you call this function called intercept

311
00:20:51,785 --> 00:20:56,700
and then this will give you access to the request and the next.

312
00:20:56,700 --> 00:21:00,550
So you could you could chain in

313
00:21:00,550 --> 00:21:05,080
a bunch of interceptors one behind the other if you so choose to,

314
00:21:05,080 --> 00:21:11,050
so that they can process the outgoing requests one after another if you so choose to.

315
00:21:11,050 --> 00:21:20,260
What this intercept does is it gives you access to the Http request message.

316
00:21:20,260 --> 00:21:23,300
So when I get access to the Http request message,

317
00:21:23,300 --> 00:21:27,810
you would notice that here I am injecting the auth service.

318
00:21:27,810 --> 00:21:33,870
Now unlike the way we were injecting services into components,

319
00:21:33,870 --> 00:21:37,295
here I'm showing a the use of an injector.

320
00:21:37,295 --> 00:21:39,995
An injector is part of the Angular code.

321
00:21:39,995 --> 00:21:44,080
So using an injector you can inject services or

322
00:21:44,080 --> 00:21:50,020
other components into other services or components.

323
00:21:50,020 --> 00:21:57,495
So here you see that I am injecting the auth service in here by using this.

324
00:21:57,495 --> 00:22:04,690
Now one other reason is that if I directly inject the service into my constructor,

325
00:22:04,690 --> 00:22:11,545
it will develop a circular dependency between the interceptor and the authService,

326
00:22:11,545 --> 00:22:15,200
and that will cause your code not to work.

327
00:22:15,200 --> 00:22:18,190
So this is a work around to the problems.

328
00:22:18,190 --> 00:22:21,430
So that your interceptor- because I need the

329
00:22:21,430 --> 00:22:25,810
authService,in order to get hold of the token from

330
00:22:25,810 --> 00:22:31,680
the authService and authService in turn depends on this interceptor so that's

331
00:22:31,680 --> 00:22:38,760
why in order to break the loop I am explicitly injecting the authService in this case.

332
00:22:38,760 --> 00:22:42,630
Now this is something that I have figured out by trial

333
00:22:42,630 --> 00:22:47,080
and error I initially went ahead and simply injected

334
00:22:47,080 --> 00:22:49,600
the odd services to the constructor and then found that

335
00:22:49,600 --> 00:22:54,270
Angular was not compiling the code then I figured out that

336
00:22:54,270 --> 00:23:01,510
there was an error there and then after doing some Google search then

337
00:23:01,510 --> 00:23:05,330
found out that this is an alternative way of handling

338
00:23:05,330 --> 00:23:09,620
the same thing and this works out much better for our application.

339
00:23:09,620 --> 00:23:13,560
So once I inject the authService from the service I get

340
00:23:13,560 --> 00:23:17,555
hold of the token and then notice what I am doing here.

341
00:23:17,555 --> 00:23:23,200
Here I'm saying clone const auth req req clone.

342
00:23:23,200 --> 00:23:29,380
So we will clone the request and then we will set up in the headers.

343
00:23:29,380 --> 00:23:32,110
So we'll say req headers set

344
00:23:32,110 --> 00:23:35,240
authorization and then notice what I am

345
00:23:35,240 --> 00:23:38,005
setting up the authorization header to be, bearer.

346
00:23:38,005 --> 00:23:42,100
Plus authToken.

347
00:23:42,100 --> 00:23:47,360
So in the authorization header I am setting up the bearer and authToken here.

348
00:23:47,360 --> 00:23:49,550
So that is how I am setting up

349
00:23:49,550 --> 00:23:53,080
the authorization header in

350
00:23:53,080 --> 00:23:57,465
the outgoing request message in my Angular application. So right there.

351
00:23:57,465 --> 00:24:01,660
And that's how I ensured that all outgoing requests will

352
00:24:01,660 --> 00:24:06,645
have the authorization header set up before they are passed to the server side.

353
00:24:06,645 --> 00:24:12,775
And then after that, we will simply pass it on to the next interceptor, if it exists,

354
00:24:12,775 --> 00:24:15,140
or onto the outgoing queue,

355
00:24:15,140 --> 00:24:19,935
so that request message will be sent out to the server side.

356
00:24:19,935 --> 00:24:24,830
Similarly, I have another interceptor that I have implemented here.

357
00:24:24,830 --> 00:24:30,260
This interceptor intercepts any unauthorized reply messages

358
00:24:30,260 --> 00:24:31,800
that are coming back from the server side.

359
00:24:31,800 --> 00:24:37,150
So, if the server replies with a 401 Unauthorized reply message.

360
00:24:37,150 --> 00:24:39,550
So at that point again, same thing,

361
00:24:39,550 --> 00:24:42,760
I have set up the authService here,

362
00:24:42,760 --> 00:24:46,410
and then, inside here then I will say,

363
00:24:46,410 --> 00:24:49,060
do handle if error.

364
00:24:49,060 --> 00:24:54,800
So this is where I will get hold of the HttpEvent here.

365
00:24:54,800 --> 00:25:04,580
The HttpEvent is a lower-level object than a request,

366
00:25:04,580 --> 00:25:08,630
but that allows us to get access to the incoming reply message,

367
00:25:08,630 --> 00:25:12,530
and then so we will check to see if there is an error,

368
00:25:12,530 --> 00:25:17,235
and then if error is an instance of HTTP error response,

369
00:25:17,235 --> 00:25:20,770
and if the error status is 401.

370
00:25:20,770 --> 00:25:28,220
So which means that I have just detected that the server sent back a 401 error message.

371
00:25:28,220 --> 00:25:32,305
So which means that there were some authorization problem on the server side.

372
00:25:32,305 --> 00:25:33,790
Then at that point I will check

373
00:25:33,790 --> 00:25:37,620
the json web token to make sure that the json web token is still valid.

374
00:25:37,620 --> 00:25:39,030
If it is not valid,

375
00:25:39,030 --> 00:25:44,910
then I will discard my credentials and expect the user to login all over again.

376
00:25:44,910 --> 00:25:48,880
So that way I will ensure that if my json web token

377
00:25:48,880 --> 00:25:53,480
expires in the process of trying to fetch data,

378
00:25:53,480 --> 00:25:58,045
that will still be intercepted by here because if the server responds with a 401,

379
00:25:58,045 --> 00:26:00,280
I will intercept that and then clear out

380
00:26:00,280 --> 00:26:03,830
my json web token and I expect the user to login all over again.

381
00:26:03,830 --> 00:26:08,750
We can also redirect the user to the login page if you want to,

382
00:26:08,750 --> 00:26:12,330
but with the Angular application it's a bit more complicated

383
00:26:12,330 --> 00:26:16,275
to do that and I didn't want to confuse you by doing all that.

384
00:26:16,275 --> 00:26:19,385
Instead, I am simply logging out

385
00:26:19,385 --> 00:26:22,500
the user at this point and then destroying the user credentials,

386
00:26:22,500 --> 00:26:25,855
so that the user will be expected to login at that point.

387
00:26:25,855 --> 00:26:33,880
So, simple handling of how we inject the authorization header into the outgoing request,

388
00:26:33,880 --> 00:26:38,850
and also intercept any 401 unauthorized messages

389
00:26:38,850 --> 00:26:40,820
that are coming back from the server side.

390
00:26:40,820 --> 00:26:45,860
So, you see how these additional changes need to be

391
00:26:45,860 --> 00:26:51,955
made to your Angular application in order to make it work with your server side.

392
00:26:51,955 --> 00:26:55,125
With the authentication part set in,

393
00:26:55,125 --> 00:26:58,200
if you didn't have authentication and if you were just going to

394
00:26:58,200 --> 00:27:02,485
access the rest API endpoints and do get operations,

395
00:27:02,485 --> 00:27:05,240
you don't even need to worry about any of these things.

396
00:27:05,240 --> 00:27:06,790
No authentication is required.

397
00:27:06,790 --> 00:27:09,140
Data can be fetched very easily.

398
00:27:09,140 --> 00:27:10,590
But for any post,

399
00:27:10,590 --> 00:27:12,395
put and delete operations,

400
00:27:12,395 --> 00:27:15,630
we need to support all these features.

401
00:27:15,630 --> 00:27:21,375
So that's the reason why I have implemented the authentication part into my application.

402
00:27:21,375 --> 00:27:23,995
Also as I illustrated earlier,

403
00:27:23,995 --> 00:27:26,985
when no user is logged in,

404
00:27:26,985 --> 00:27:32,570
then we will not be able to navigate to the my favorites endpoint,

405
00:27:32,570 --> 00:27:35,035
but when a user is logged in,

406
00:27:35,035 --> 00:27:40,420
then we will be able to see the my favorites for the specific user.

407
00:27:40,420 --> 00:27:45,095
This is implemented by using route guards in Angular.

408
00:27:45,095 --> 00:27:47,995
Now to implement these route guards,

409
00:27:47,995 --> 00:27:52,080
I have implemented another service here called the AuthGuardService.

410
00:27:52,080 --> 00:27:54,170
So in this AuthGuardService,

411
00:27:54,170 --> 00:27:57,970
we implemented this method called canActivate method which

412
00:27:57,970 --> 00:28:02,225
we will subclass in order to implement this.

413
00:28:02,225 --> 00:28:05,705
And in the canActivate method,

414
00:28:05,705 --> 00:28:08,550
the implementation will return a boolean,

415
00:28:08,550 --> 00:28:10,090
and in this case,

416
00:28:10,090 --> 00:28:15,630
what we check for is if this user is logged in,

417
00:28:15,630 --> 00:28:18,605
then we will allow the user to navigate.

418
00:28:18,605 --> 00:28:25,480
Otherwise, you will navigate the user to the home endpoint.

419
00:28:25,480 --> 00:28:31,175
So that's the way the route guard is implemented in this case.

420
00:28:31,175 --> 00:28:33,955
Now, to make use of this route guard,

421
00:28:33,955 --> 00:28:41,780
we will go to see how the routes are updated to make use of the route guards.

422
00:28:41,780 --> 00:28:44,520
So in the routes.ts file,

423
00:28:44,520 --> 00:28:50,435
you can see that for the favorites component,

424
00:28:50,435 --> 00:28:54,510
we see that we specify the path as favorites and the component as

425
00:28:54,510 --> 00:28:58,620
FavoritesComponent and then we specify this other field

426
00:28:58,620 --> 00:29:07,785
called canActivate for which we specified AuthGuard as the parameter here,

427
00:29:07,785 --> 00:29:12,445
and this AuthGuard is nothing but the AuthGuard service that we have implemented,

428
00:29:12,445 --> 00:29:14,825
which is imported here.

429
00:29:14,825 --> 00:29:20,405
So this way when the AuthGuard evaluates to false,

430
00:29:20,405 --> 00:29:24,755
then you will not be allowed to navigate to the favorites component,

431
00:29:24,755 --> 00:29:28,105
instead, you will be redirected to home,

432
00:29:28,105 --> 00:29:36,245
but when the user is logged in then obviously the AuthGuard will evaluate to true,

433
00:29:36,245 --> 00:29:37,390
and in this case,

434
00:29:37,390 --> 00:29:41,665
then you will be able to navigate to the favorites route there.

435
00:29:41,665 --> 00:29:49,700
Now also similarly there are minor modifications to the remaining components in there,

436
00:29:49,700 --> 00:29:52,200
which allow you to to deal with

437
00:29:52,200 --> 00:29:57,365
the intricacies of how your client and server will talk to each other.

438
00:29:57,365 --> 00:30:02,555
In particular, note how the header component has been updated to

439
00:30:02,555 --> 00:30:08,195
reflect the user's logged in status in the toolbar at the top.

440
00:30:08,195 --> 00:30:11,500
That is again another interesting change that I have

441
00:30:11,500 --> 00:30:15,710
made to the header component in our application.

442
00:30:15,710 --> 00:30:20,220
So I will leave that as an exercise for you to figure out how that has been implemented.

443
00:30:20,220 --> 00:30:22,160
Very simple code there.

444
00:30:22,160 --> 00:30:24,660
Should be easy for you to figure that out.

445
00:30:24,660 --> 00:30:28,020
So with all these changes, now,

446
00:30:28,020 --> 00:30:32,095
my angular client is able to interact with my server.

447
00:30:32,095 --> 00:30:36,540
Let me again show you how we can post some comments to the server,

448
00:30:36,540 --> 00:30:41,995
and then see the comment immediately reflected into the dish.

449
00:30:41,995 --> 00:30:45,325
So, again going back to our application,

450
00:30:45,325 --> 00:30:50,050
we can now go to the menu and then pull up any dish here,

451
00:30:50,050 --> 00:30:52,740
and I can post comments to the dish here,

452
00:30:52,740 --> 00:30:59,600
so I would immediately set up the rating here,

453
00:30:59,600 --> 00:31:02,540
and my comment value here.

454
00:31:03,540 --> 00:31:06,700
Notice that I am not inputting

455
00:31:06,700 --> 00:31:15,735
my username or my author's name here in the form here.

456
00:31:15,735 --> 00:31:18,470
Now of course, in order to submit a comment,

457
00:31:18,470 --> 00:31:19,590
you need to be logged in.

458
00:31:19,590 --> 00:31:24,520
So if you are not logged in this comment will not be accepted by my server.

459
00:31:24,520 --> 00:31:26,935
So let me first log myself in.

460
00:31:26,935 --> 00:31:32,890
So I can login here.

461
00:31:32,890 --> 00:31:34,220
And the moment I login,

462
00:31:34,220 --> 00:31:39,255
you immediately notice that header toolbar is updated to indicate my status.

463
00:31:39,255 --> 00:31:41,375
Now I can post this comment.

464
00:31:41,375 --> 00:31:43,990
And you would notice that when I post the comment,

465
00:31:43,990 --> 00:31:46,440
the comment is added into the list of the comments,

466
00:31:46,440 --> 00:31:50,575
and also notice that the author field is automatically filled in here.

467
00:31:50,575 --> 00:31:54,040
Because that is how we set up our server side.

468
00:31:54,040 --> 00:31:55,570
In the comments field,

469
00:31:55,570 --> 00:31:58,880
we have set up our user as

470
00:31:58,880 --> 00:32:05,890
a reference to the user information

471
00:32:05,890 --> 00:32:09,755
that we store in our server side,and since we use the populate,

472
00:32:09,755 --> 00:32:11,585
Mongoose Populate on the server side,

473
00:32:11,585 --> 00:32:14,080
the user information is automatically populated

474
00:32:14,080 --> 00:32:16,715
into the incoming comments from the server side.

475
00:32:16,715 --> 00:32:21,130
So, that is how you notice how I am leveraging what

476
00:32:21,130 --> 00:32:25,615
the server already provides for me to automatically fill in the details.

477
00:32:25,615 --> 00:32:31,180
So, minor changes again even into

478
00:32:31,180 --> 00:32:38,880
the dish detail page to reflect the use of the comments support on the server side.

479
00:32:38,880 --> 00:32:43,769
With this I complete the quick illustration

480
00:32:43,769 --> 00:32:49,575
of the Angular client that we have implemented as part of this exercise.

481
00:32:49,575 --> 00:32:55,990
And I hope that you go through the details of the code in the Angular client also,

482
00:32:55,990 --> 00:32:59,410
and then reflect back on what you have learned in the Angular course and see

483
00:32:59,410 --> 00:33:03,105
how the modifications enable us to implement

484
00:33:03,105 --> 00:33:06,350
in a modified angular client which is now

485
00:33:06,350 --> 00:33:09,705
able to communicate with the server and then support all the features

486
00:33:09,705 --> 00:33:17,310
that we originally intended to implement as part of both the client and the server side.