﻿1
00:00:00,782 --> 00:00:02,520
‫So in this lecture,

2
00:00:02,520 --> 00:00:04,590
‫we're gonna use the position data

3
00:00:04,590 --> 00:00:07,410
‫in order to fetch all necessary information

4
00:00:07,410 --> 00:00:10,353
‫about the city where the user has clicked.

5
00:00:11,910 --> 00:00:15,478
‫So for example, if the user clicks here on Rome,

6
00:00:15,478 --> 00:00:19,920
‫then we want to automatically fetch that data here

7
00:00:19,920 --> 00:00:24,330
‫from an API, so from a reverse geocoding API.

8
00:00:24,330 --> 00:00:27,120
‫And so let's now go do that.

9
00:00:27,120 --> 00:00:29,280
‫So let's open up our form,

10
00:00:29,280 --> 00:00:31,710
‫and now the first thing that we need to do is

11
00:00:31,710 --> 00:00:34,080
‫to actually get the location data

12
00:00:34,080 --> 00:00:37,020
‫from the URL into this component.

13
00:00:37,020 --> 00:00:38,130
‫So reading here,

14
00:00:38,130 --> 00:00:41,403
‫this global state that is stored in the url.

15
00:00:42,540 --> 00:00:45,060
‫Now we already did the same thing before

16
00:00:45,060 --> 00:00:48,330
‫which is right here in the map, right?

17
00:00:48,330 --> 00:00:51,210
‫So the map also depends on that data

18
00:00:51,210 --> 00:00:54,990
‫in order to move to the city that the user has clicked.

19
00:00:54,990 --> 00:00:58,380
‫So that's this logic right here, plus this.

20
00:00:58,380 --> 00:01:00,960
‫Now should we just go copy paste this

21
00:01:00,960 --> 00:01:03,150
‫into this other component?

22
00:01:03,150 --> 00:01:05,850
‫Well, I think that it actually makes sense

23
00:01:05,850 --> 00:01:09,243
‫to create a new custom hook now.

24
00:01:10,920 --> 00:01:13,563
‫So let's call this useURLPosition.js.

25
00:01:19,018 --> 00:01:23,593
‫All right, and so then let's move that here

26
00:01:23,593 --> 00:01:25,890
‫and grab all this.

27
00:01:25,890 --> 00:01:29,550
‫And so now we are extracting some more stateful logic

28
00:01:29,550 --> 00:01:31,143
‫into a custom hook.

29
00:01:32,280 --> 00:01:33,303
‫Now in this case,

30
00:01:34,467 --> 00:01:37,190
‫well let's first create a function here.

31
00:01:37,190 --> 00:01:38,440
‫useUrlPosition.

32
00:01:43,200 --> 00:01:45,120
‫So as I was saying, here,

33
00:01:45,120 --> 00:01:47,820
‫we are actually creating a custom hook

34
00:01:47,820 --> 00:01:50,700
‫on top of another custom hook.

35
00:01:50,700 --> 00:01:53,400
‫So this is also a custom hook that is coming

36
00:01:53,400 --> 00:01:57,030
‫from React Router, but this is perfectly fine.

37
00:01:57,030 --> 00:02:01,260
‫So as long as our logic has at least one React hook,

38
00:02:01,260 --> 00:02:03,600
‫we need to create our own custom hook

39
00:02:03,600 --> 00:02:06,033
‫if we want to reuse that logic.

40
00:02:07,020 --> 00:02:11,959
‫So now we need to include, start to import, that here.

41
00:02:11,959 --> 00:02:16,620
‫And then what we want is to return.

42
00:02:16,620 --> 00:02:20,703
‫And here, let's just actually give them more generic names,

43
00:02:22,982 --> 00:02:25,473
‫because this is meant to be reusable.

44
00:02:28,830 --> 00:02:31,653
‫And so yeah, let's export this.

45
00:02:32,730 --> 00:02:34,710
‫And with this, we are done.

46
00:02:34,710 --> 00:02:38,190
‫And so then whenever we need to position from the url,

47
00:02:38,190 --> 00:02:43,190
‫we very simply just call this one function, and that's it.

48
00:02:45,570 --> 00:02:48,087
‫So here, let's then import that data.

49
00:02:48,087 --> 00:02:53,087
‫And here we can now again call it mapLat, and mapLng,

50
00:02:54,840 --> 00:02:55,863
‫from useUrlLocation.

51
00:03:00,060 --> 00:03:03,810
‫So somehow there's no auto import,

52
00:03:03,810 --> 00:03:07,200
‫so let's do that ourselves.

53
00:03:07,200 --> 00:03:09,587
‫So useUrlLocation like this,

54
00:03:13,440 --> 00:03:15,690
‫and that actually doesn't work.

55
00:03:15,690 --> 00:03:19,980
‫And I guess that's because it is actually called position.

56
00:03:19,980 --> 00:03:21,563
‫So useUrlPosition.

57
00:03:22,980 --> 00:03:25,303
‫So let's fix that URLPosition.

58
00:03:28,836 --> 00:03:29,760
‫And so with that,

59
00:03:29,760 --> 00:03:32,880
‫the map is back to working just like before.

60
00:03:32,880 --> 00:03:37,530
‫And so then we can just grab this line of code,

61
00:03:37,530 --> 00:03:39,663
‫and use it inside our form.

62
00:03:41,580 --> 00:03:43,336
‫So placing that right here.

63
00:03:43,336 --> 00:03:47,253
‫Let's try to import this now.

64
00:03:48,270 --> 00:03:49,830
‫And there we go.

65
00:03:49,830 --> 00:03:54,830
‫So now inside the form, we should have also the location.

66
00:03:56,820 --> 00:03:58,443
‫So this is somehow not working.

67
00:03:59,670 --> 00:04:00,753
‫So let's see.

68
00:04:01,873 --> 00:04:03,423
‫Here it is.

69
00:04:05,490 --> 00:04:08,313
‫Well, that's actually apparently not working,

70
00:04:09,180 --> 00:04:12,063
‫so there's nothing in here.

71
00:04:16,260 --> 00:04:20,553
‫So let's see if actually the app still works here,

72
00:04:22,590 --> 00:04:23,733
‫and yeah, it does.

73
00:04:25,020 --> 00:04:27,470
‫Well, let's try to lock this to the console here.

74
00:04:29,790 --> 00:04:32,373
‫Maybe I just somehow didn't see it.

75
00:04:37,230 --> 00:04:38,670
‫Yeah, there we go.

76
00:04:38,670 --> 00:04:40,890
‫So that's working indeed.

77
00:04:40,890 --> 00:04:43,020
‫And so let's now use this data

78
00:04:43,020 --> 00:04:46,140
‫to actually do the reverse geocoding.

79
00:04:46,140 --> 00:04:50,070
‫So getting the city information, or really any information,

80
00:04:50,070 --> 00:04:54,363
‫about the GPS position that we are currently located at.

81
00:04:55,530 --> 00:04:58,683
‫Let's just call this lat, and lng.

82
00:04:59,910 --> 00:05:04,320
‫And then we want to fetch this data

83
00:05:04,320 --> 00:05:06,153
‫right when the component mounts.

84
00:05:07,560 --> 00:05:10,500
‫So that's a useEffect for that.

85
00:05:10,500 --> 00:05:13,410
‫Now, the data that we're gonna fetch here is not going

86
00:05:13,410 --> 00:05:16,140
‫to go into our global state,

87
00:05:16,140 --> 00:05:19,140
‫so into the global city's context,

88
00:05:19,140 --> 00:05:21,780
‫because this data is only relevant

89
00:05:21,780 --> 00:05:25,110
‫for then creating a city's object that will be added

90
00:05:25,110 --> 00:05:25,943
‫to the array.

91
00:05:26,790 --> 00:05:30,270
‫So you only really need this data right here

92
00:05:30,270 --> 00:05:31,590
‫in this component.

93
00:05:31,590 --> 00:05:33,873
‫And so then we just fetched it right here.

94
00:05:35,220 --> 00:05:40,220
‫Alright so let's, as always, create an async function,

95
00:05:41,970 --> 00:05:46,970
‫and then fetchCityData for example.

96
00:05:50,186 --> 00:05:53,277
‫And then a try catch block as always.

97
00:05:54,450 --> 00:05:58,290
‫So we're going to need a few pieces of state here apart

98
00:05:58,290 --> 00:06:00,040
‫from the ones that we already have.

99
00:06:01,971 --> 00:06:04,450
‫So first, let's say, is loading,

100
00:06:06,120 --> 00:06:07,863
‫then let's say geocoding,

101
00:06:09,450 --> 00:06:13,893
‫and then setIsLoadingGeocoding.

102
00:06:15,000 --> 00:06:18,000
‫And again, I'm using a different name here

103
00:06:18,000 --> 00:06:22,890
‫because we already used IsLoading in our context,

104
00:06:22,890 --> 00:06:23,973
‫so somewhere else.

105
00:06:28,590 --> 00:06:31,860
‫So here we then start by setting this to true,

106
00:06:31,860 --> 00:06:35,700
‫then we will have our catch block as always.

107
00:06:35,700 --> 00:06:39,570
‫And then also the finally block, where in the end,

108
00:06:39,570 --> 00:06:44,493
‫we setIsLoading back to false.

109
00:06:45,630 --> 00:06:46,470
‫Okay?

110
00:06:46,470 --> 00:06:48,480
‫So that's one of the states.

111
00:06:48,480 --> 00:06:51,993
‫And then let's also create one to store the city name.

112
00:06:53,086 --> 00:06:57,480
‫cityName, setCityName, or actually we already have those.

113
00:06:57,480 --> 00:07:00,453
‫So city name and country are already up there.

114
00:07:02,310 --> 00:07:04,503
‫So let's just move this one over there.

115
00:07:05,370 --> 00:07:09,513
‫And so then let's keep writing our code here.

116
00:07:11,670 --> 00:07:15,510
‫So as always, let's create a variable called response,

117
00:07:15,510 --> 00:07:18,903
‫which will await fetching the actual data.

118
00:07:19,920 --> 00:07:22,140
‫And here at the top of this file,

119
00:07:22,140 --> 00:07:24,573
‫you should already have the url.

120
00:07:25,560 --> 00:07:30,560
‫So let's grab that and I will paste down here.

121
00:07:31,020 --> 00:07:33,690
‫And then out here, I will create, again,

122
00:07:33,690 --> 00:07:37,083
‫a variable called BASE_URL.

123
00:07:39,900 --> 00:07:42,123
‫And so this is basically all of this,

124
00:07:43,620 --> 00:07:45,813
‫but then without the more specific part.

125
00:07:47,340 --> 00:07:52,340
‫Okay, and so then let's here build the actual url.

126
00:07:54,240 --> 00:07:58,620
‫So we want the BASE_URL, and then as we see here,

127
00:07:58,620 --> 00:08:03,620
‫we add the latitude and the longitude like this.

128
00:08:06,613 --> 00:08:07,446
‫Okay?

129
00:08:08,970 --> 00:08:12,150
‫And so then here is where we use that data.

130
00:08:12,150 --> 00:08:15,183
‫So the latitude that we got from our URL,

131
00:08:18,083 --> 00:08:21,390
‫and the longitude, okay?

132
00:08:21,390 --> 00:08:24,450
‫And immediately React is telling us that we now need

133
00:08:24,450 --> 00:08:28,830
‫to add them as a dependency, which makes total sense.

134
00:08:28,830 --> 00:08:31,020
‫Or actually let me not add it for now,

135
00:08:31,020 --> 00:08:33,750
‫so that I can show you later what's gonna happen

136
00:08:33,750 --> 00:08:35,490
‫if we don't do that.

137
00:08:35,490 --> 00:08:37,983
‫So that's gonna be a nice exercise, I think.

138
00:08:39,900 --> 00:08:44,900
‫So then we await res.json from there.

139
00:08:46,630 --> 00:08:47,820
‫And then as always,

140
00:08:47,820 --> 00:08:51,240
‫let's just log that to the console first.

141
00:08:51,240 --> 00:08:53,390
‫Then we need to call the function out here.

142
00:08:58,890 --> 00:09:00,810
‫Let's reload that.

143
00:09:00,810 --> 00:09:03,723
‫And here we immediately get something.

144
00:09:05,190 --> 00:09:07,590
‫So I'm not really sure where I clicked,

145
00:09:07,590 --> 00:09:09,480
‫but apparently we clicked on some city

146
00:09:09,480 --> 00:09:12,123
‫called Val de Mecca or something like that.

147
00:09:13,140 --> 00:09:16,260
‫So this is basically what we want here.

148
00:09:16,260 --> 00:09:20,823
‫So the locality, or there should actually also be a city.

149
00:09:22,020 --> 00:09:25,020
‫So that's not really appearing right now.

150
00:09:25,020 --> 00:09:27,780
‫So let me now demonstrate what happens

151
00:09:27,780 --> 00:09:30,030
‫if I click somewhere else.

152
00:09:30,030 --> 00:09:32,141
‫So now with this still open,

153
00:09:32,141 --> 00:09:35,283
‫if I click here for example on Rome,

154
00:09:36,299 --> 00:09:39,270
‫then you see that nothing happened,

155
00:09:39,270 --> 00:09:42,150
‫even though the URL there has changed.

156
00:09:42,150 --> 00:09:47,100
‫So basically the latitude and longitude have changed right?

157
00:09:47,100 --> 00:09:49,920
‫However, we didn't fetch any new data.

158
00:09:49,920 --> 00:09:52,740
‫And so do you know why that is?

159
00:09:52,740 --> 00:09:55,530
‫Well, it's because we are missing these values here

160
00:09:55,530 --> 00:09:57,480
‫in the dependency array.

161
00:09:57,480 --> 00:09:59,400
‫So this function here has no way

162
00:09:59,400 --> 00:10:02,517
‫of knowing that this data has actually changed,

163
00:10:02,517 --> 00:10:05,913
‫and so therefore the effect is then not executed again.

164
00:10:07,530 --> 00:10:09,660
‫But if we pass both of them in,

165
00:10:09,660 --> 00:10:14,660
‫then our effect will know that there has been a change.

166
00:10:14,790 --> 00:10:17,760
‫So now here we get the city property

167
00:10:17,760 --> 00:10:20,970
‫which is what we want to use usually.

168
00:10:20,970 --> 00:10:23,850
‫Now if we're just clicking on some small place,

169
00:10:23,850 --> 00:10:25,650
‫like in the middle of nowhere,

170
00:10:25,650 --> 00:10:27,270
‫then the city's gonna be empty,

171
00:10:27,270 --> 00:10:29,883
‫and so then we can just use the locality.

172
00:10:32,130 --> 00:10:37,130
‫So let's then set the city name to data.city,

173
00:10:38,400 --> 00:10:42,393
‫and if that doesn't exist, then we do data.locality.

174
00:10:46,440 --> 00:10:47,940
‫And then let's just account

175
00:10:47,940 --> 00:10:51,270
‫for the case where that also doesn't exist.

176
00:10:51,270 --> 00:10:53,720
‫And so then let's just set it to an empty string.

177
00:10:55,036 --> 00:10:58,200
‫Then here we also get the country name,

178
00:10:58,200 --> 00:11:00,630
‫and so let's also set the country name,

179
00:11:00,630 --> 00:11:02,400
‫because later on we will want

180
00:11:02,400 --> 00:11:07,400
‫to set that country also to the new city object.

181
00:11:08,310 --> 00:11:10,693
‫So that's data.countryName.

182
00:11:13,740 --> 00:11:15,690
‫And if we take a look here,

183
00:11:15,690 --> 00:11:18,960
‫then you'll see that actually it already changed here.

184
00:11:18,960 --> 00:11:21,420
‫So that's because down here in our JSX,

185
00:11:21,420 --> 00:11:25,650
‫we are already referencing the city name right here.

186
00:11:25,650 --> 00:11:28,020
‫And so that is already working.

187
00:11:28,020 --> 00:11:29,520
‫So let's click somewhere else.

188
00:11:30,540 --> 00:11:33,480
‫Like here it says Latina, so let's see.

189
00:11:33,480 --> 00:11:37,113
‫And indeed it then changes everywhere here to Latina.

190
00:11:38,160 --> 00:11:39,810
‫Then what we also want to do is

191
00:11:39,810 --> 00:11:43,110
‫to convert that country name to an emoji,

192
00:11:43,110 --> 00:11:45,813
‫so that we can then use that right here.

193
00:11:47,310 --> 00:11:49,650
‫So how do we do that?

194
00:11:49,650 --> 00:11:53,700
‫So should we create another piece of state here for that?

195
00:11:53,700 --> 00:11:56,910
‫Well, that's actually not really necessary.

196
00:11:56,910 --> 00:12:00,090
‫So we can just derive that using this function

197
00:12:00,090 --> 00:12:01,623
‫that it already provided here.

198
00:12:02,460 --> 00:12:07,345
‫So we can just calculate emoji here based

199
00:12:07,345 --> 00:12:09,600
‫on that information.

200
00:12:09,600 --> 00:12:13,390
‫So convertToEmoji, and then this simply receives

201
00:12:14,640 --> 00:12:16,440
‫a country code.

202
00:12:16,440 --> 00:12:20,130
‫Well, we actually don't have that country code anywhere.

203
00:12:20,130 --> 00:12:22,350
‫So that's this one right here.

204
00:12:22,350 --> 00:12:23,610
‫So we don't have that.

205
00:12:23,610 --> 00:12:26,280
‫So if we want to get that out here,

206
00:12:26,280 --> 00:12:29,040
‫we would have to create another piece of state.

207
00:12:29,040 --> 00:12:33,480
‫And so instead, let's actually break what I just said,

208
00:12:33,480 --> 00:12:37,323
‫and create a state variable for the emoji after all,

209
00:12:38,640 --> 00:12:40,713
‫setEmoji, and then useState.

210
00:12:43,410 --> 00:12:45,300
‫So you have so many pieces of state here

211
00:12:45,300 --> 00:12:48,990
‫that it might even make sense to use a useReducer

212
00:12:48,990 --> 00:12:52,345
‫at this point, but here let's just keep it simple,

213
00:12:52,345 --> 00:12:55,353
‫and then setEmoji right here.

214
00:12:56,754 --> 00:12:59,730
‫So this is not a big problem of having all

215
00:12:59,730 --> 00:13:02,730
‫of these different states because these data updates,

216
00:13:02,730 --> 00:13:04,110
‫as we learned before,

217
00:13:04,110 --> 00:13:07,863
‫are going to be batched at least since React version 18.

218
00:13:09,690 --> 00:13:13,500
‫So then here we can call that function convertToEmoji,

219
00:13:13,500 --> 00:13:16,213
‫and then it's data.countryCode.

220
00:13:19,080 --> 00:13:23,490
‫So let's see, then we need to remove that here.

221
00:13:23,490 --> 00:13:26,043
‫And beautiful, there it is.

222
00:13:26,879 --> 00:13:28,440
‫Nice.

223
00:13:28,440 --> 00:13:30,150
‫So we are almost done here,

224
00:13:30,150 --> 00:13:33,540
‫but now let's account for a different situation.

225
00:13:33,540 --> 00:13:35,820
‫So let's say I click somewhere here,

226
00:13:35,820 --> 00:13:36,900
‫in the middle of nowhere.

227
00:13:36,900 --> 00:13:40,740
‫So in the water where nothing really is.

228
00:13:40,740 --> 00:13:45,210
‫So then we see that the city name is this weird thing.

229
00:13:45,210 --> 00:13:48,570
‫Or if I click here, then well,

230
00:13:48,570 --> 00:13:51,270
‫it's something that's not really meaningful.

231
00:13:51,270 --> 00:13:54,000
‫So let's see what we have.

232
00:13:54,000 --> 00:13:58,230
‫So this is not a city, it's not a country,

233
00:13:58,230 --> 00:13:59,730
‫so it's really nothing.

234
00:13:59,730 --> 00:14:03,690
‫All the tasks has this weird locality set to that.

235
00:14:03,690 --> 00:14:05,250
‫Now if I click in here,

236
00:14:05,250 --> 00:14:08,250
‫that is apparently still part of the country.

237
00:14:08,250 --> 00:14:10,590
‫So then here, everything works.

238
00:14:10,590 --> 00:14:12,941
‫But then out here in the middle of the sea,

239
00:14:12,941 --> 00:14:15,600
‫we don't have any data.

240
00:14:15,600 --> 00:14:18,330
‫So we don't have any country, for example.

241
00:14:18,330 --> 00:14:21,750
‫And so let's now then not display the form

242
00:14:21,750 --> 00:14:22,950
‫in that situation,

243
00:14:22,950 --> 00:14:26,403
‫and instead tell the user to click somewhere else.

244
00:14:27,600 --> 00:14:30,000
‫So how can we do that?

245
00:14:30,000 --> 00:14:34,533
‫Well, I think a good idea to do this is to create an error.

246
00:14:35,370 --> 00:14:39,088
‫So right here, before even setting any state,

247
00:14:39,088 --> 00:14:44,088
‫we can say that if there is no data.countryCode for example,

248
00:14:45,780 --> 00:14:50,107
‫then throw a new error saying,

249
00:14:52,717 --> 00:14:57,717
‫"That doesn't seem to be a city.

250
00:15:00,090 --> 00:15:05,090
‫Click somewhere else."

251
00:15:05,190 --> 00:15:06,723
‫More like this.

252
00:15:08,126 --> 00:15:11,223
‫And then let's just add a friendly emoji here.

253
00:15:12,620 --> 00:15:15,633
‫And here we need the double quotes.

254
00:15:17,550 --> 00:15:21,510
‫Now okay, and then here we can catch that error,

255
00:15:21,510 --> 00:15:25,080
‫and place it into our state so that then we can,

256
00:15:25,080 --> 00:15:28,443
‫depending on that state, display a message right there.

257
00:15:29,640 --> 00:15:32,590
‫So let's create another piece of state here

258
00:15:34,352 --> 00:15:38,307
‫called geocodingError and setGeocoding Error.

259
00:15:44,820 --> 00:15:47,610
‫So by default, this will be empty,

260
00:15:47,610 --> 00:15:51,273
‫and we want to make it empty also here at the beginning.

261
00:15:55,470 --> 00:15:58,470
‫So to basically reset the error.

262
00:15:58,470 --> 00:16:00,150
‫But then if there actually is an error,

263
00:16:00,150 --> 00:16:03,720
‫like this one here or even like some other error,

264
00:16:03,720 --> 00:16:08,720
‫then we want to setGeocodingError to the error.message.

265
00:16:12,210 --> 00:16:14,340
‫So whatever we pass here into the error

266
00:16:14,340 --> 00:16:17,460
‫will become error.message.

267
00:16:17,460 --> 00:16:21,300
‫And now here we can then say that

268
00:16:21,300 --> 00:16:25,773
‫if there is a geocodingError,

269
00:16:26,970 --> 00:16:30,690
‫then just return the message component

270
00:16:30,690 --> 00:16:33,540
‫that we already created earlier.

271
00:16:33,540 --> 00:16:36,330
‫So here, this then requires the message prompt

272
00:16:36,330 --> 00:16:38,580
‫which is exactly going to the geocodingError.

273
00:16:42,180 --> 00:16:44,163
‫And so that's already working.

274
00:16:45,630 --> 00:16:49,050
‫So if I click here on this city, then it works.

275
00:16:49,050 --> 00:16:52,743
‫But if I click here, then there doesn't seem to be a city.

276
00:16:53,610 --> 00:16:54,870
‫Nice.

277
00:16:54,870 --> 00:16:57,180
‫And now just one final thing,

278
00:16:57,180 --> 00:17:02,180
‫which is also the case where the city is currently loading.

279
00:17:02,460 --> 00:17:07,460
‫So isLoadingGeocoding, then return a spinner now, right?

280
00:17:12,450 --> 00:17:16,083
‫So notice that that's actually a lot better.

281
00:17:16,980 --> 00:17:20,160
‫So showing the user that something is happening.

282
00:17:20,160 --> 00:17:23,480
‫Okay, and so with this, we are now almost ready

283
00:17:23,480 --> 00:17:28,480
‫to actually add a new city like this to our city's array,

284
00:17:28,500 --> 00:17:31,170
‫so into our city state and uploading it

285
00:17:31,170 --> 00:17:33,450
‫to that fake API so that then,

286
00:17:33,450 --> 00:17:36,030
‫it ends up here into our list.

287
00:17:36,030 --> 00:17:39,723
‫And so let's move on to the next lecture and do that.

