All language subtitles for 015 Finishing Steps_en

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian Download
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:02,100 --> 00:00:05,830 So let's now refine this timer approach. 2 00:00:05,830 --> 00:00:07,870 And for example, let's clear it 3 00:00:07,870 --> 00:00:11,440 if the user logged out manually in the meantime. 4 00:00:11,440 --> 00:00:16,200 And to do that, we can use some variable here. 5 00:00:16,200 --> 00:00:19,440 We can add a variable, logoutTimer, 6 00:00:19,440 --> 00:00:22,390 which initially is undefined, 7 00:00:22,390 --> 00:00:25,260 and which is defined outside of all those functions 8 00:00:25,260 --> 00:00:30,020 so that it's a global variable in this file. 9 00:00:30,020 --> 00:00:33,170 And then when we set a timer, like here, 10 00:00:33,170 --> 00:00:37,530 we can store a reference to that timer in that variable, 11 00:00:37,530 --> 00:00:41,550 because setTimeout does return such a reference, 12 00:00:41,550 --> 00:00:44,823 such a identifier, and we can store that 13 00:00:44,823 --> 00:00:47,430 in logoutTimer, in this variable. 14 00:00:47,430 --> 00:00:49,600 And if the logoutHandler is called, 15 00:00:49,600 --> 00:00:52,550 then I wanna check if logoutTimer is set. 16 00:00:52,550 --> 00:00:55,419 And if that's the case, we can call clearTimeout 17 00:00:55,419 --> 00:00:57,860 and pass logoutTimer to it 18 00:00:57,860 --> 00:01:01,123 to clear that timer if a timer was set. 19 00:01:02,000 --> 00:01:05,300 In addition, we wanna store this timer 20 00:01:05,300 --> 00:01:07,320 or this expirationTime now, 21 00:01:07,320 --> 00:01:10,170 so that if we auto logged in the user, 22 00:01:10,170 --> 00:01:12,760 if we retrieved the token from localStorage, 23 00:01:12,760 --> 00:01:15,190 we only use that as an initialToken 24 00:01:16,080 --> 00:01:20,490 if there is a remaining duration for that token. 25 00:01:20,490 --> 00:01:24,440 Because if the user did log in three hours ago, 26 00:01:24,440 --> 00:01:29,440 then that token which was stored, is not worth much anymore. 27 00:01:30,120 --> 00:01:32,640 So what I wanna do here, is I wanna look 28 00:01:32,640 --> 00:01:36,350 into my localStorage and get the token from there 29 00:01:36,350 --> 00:01:39,400 only if the token is valid. 30 00:01:39,400 --> 00:01:43,363 And I wanna delete it, if it's not valid anymore. 31 00:01:44,340 --> 00:01:47,180 For this, I'll add another helper function here, 32 00:01:47,180 --> 00:01:50,700 which you could of course also put into a brand new file, 33 00:01:50,700 --> 00:01:52,130 but I'll manage it here, 34 00:01:52,130 --> 00:01:53,923 which we'll name, retrieveStoredToken. 35 00:01:56,670 --> 00:02:01,510 And here in this function, I wanna get my token, 36 00:02:01,510 --> 00:02:03,713 I wanna get my storedToken, 37 00:02:05,500 --> 00:02:09,130 but I also wanna get my storedExpirationDate. 38 00:02:09,130 --> 00:02:12,230 And for this of course, we need to store it first of all. 39 00:02:12,230 --> 00:02:15,710 So in the loginHandler, when we use that expirationTime 40 00:02:15,710 --> 00:02:18,870 to calculate the duration and set the timer, 41 00:02:18,870 --> 00:02:22,460 I also wanna store it next to my token. 42 00:02:22,460 --> 00:02:26,200 So in localStorage, I'll set our item here 43 00:02:26,200 --> 00:02:31,200 which is the expirationTime or however you wanna name it, 44 00:02:31,680 --> 00:02:34,123 where I store expirationTime. 45 00:02:35,080 --> 00:02:38,090 And important, that now has to be a string, 46 00:02:38,090 --> 00:02:40,743 which it is the way we set it up here. 47 00:02:41,890 --> 00:02:44,900 So now we set that whenever we log in. 48 00:02:44,900 --> 00:02:48,363 Now since we do that, here in retrieveStoredToken, 49 00:02:49,690 --> 00:02:51,390 we can reach out to localStorage 50 00:02:51,390 --> 00:02:54,793 and get that expirationTime, like this. 51 00:02:55,920 --> 00:02:59,920 And now we can check whether we have some remaining time. 52 00:02:59,920 --> 00:03:03,800 So we can get that remainingTime here 53 00:03:03,800 --> 00:03:06,650 by calling calculateRemainingTime 54 00:03:06,650 --> 00:03:11,543 and passing that storedExpirationDate to that function. 55 00:03:12,570 --> 00:03:17,570 And if remainingTime is smaller or equal than zero, 56 00:03:18,960 --> 00:03:22,090 or maybe you even specify some threshold 57 00:03:22,090 --> 00:03:27,090 of let's say, one minute, which would be 3600 milliseconds, 58 00:03:28,050 --> 00:03:31,590 where you say it doesn't make sense to log the user in, 59 00:03:31,590 --> 00:03:34,380 then we wanna not log the user in. 60 00:03:34,380 --> 00:03:37,030 So then I return null here. 61 00:03:37,030 --> 00:03:38,593 We don't retrieve a token. 62 00:03:39,610 --> 00:03:42,400 We also might want to delete that data 63 00:03:42,400 --> 00:03:44,100 in localStorage then. 64 00:03:44,100 --> 00:03:48,310 So we might want to remove our token then 65 00:03:48,310 --> 00:03:53,310 and remove our expirationTime here. 66 00:03:55,220 --> 00:03:57,260 If we make it past this, if check though, 67 00:03:57,260 --> 00:03:59,100 we know that we have a valid token 68 00:03:59,100 --> 00:04:01,770 because there's enough remaining time. 69 00:04:01,770 --> 00:04:06,020 And then I wanna return that storedToken instead. 70 00:04:06,020 --> 00:04:09,440 And I actually don't just wanna return the storedToken, 71 00:04:09,440 --> 00:04:12,000 I also wanna return that remainingTime 72 00:04:12,000 --> 00:04:15,253 so that an appropriate timer can be set. 73 00:04:16,260 --> 00:04:18,899 So I'll return an object here with the token 74 00:04:18,899 --> 00:04:23,090 which is my storedToken and the duration, 75 00:04:23,090 --> 00:04:26,370 or however you wanna name it, which is my remainingTime. 76 00:04:28,230 --> 00:04:31,490 And it's now this retrieveStoredToken function 77 00:04:31,490 --> 00:04:36,020 which we wanna call here in the AuthContextProvider. 78 00:04:36,020 --> 00:04:37,930 The tokenData is then the result 79 00:04:37,930 --> 00:04:40,630 of calling retrieveStoredToken 80 00:04:40,630 --> 00:04:42,733 and tokenData is this object. 81 00:04:44,110 --> 00:04:46,003 And the initialToken therefore is tokenData.token. 82 00:04:51,190 --> 00:04:53,570 However, that will only be available 83 00:04:53,570 --> 00:04:57,100 if we did not return null here. 84 00:04:57,100 --> 00:05:01,730 And therefore of course, I actually wanna check here. 85 00:05:01,730 --> 00:05:06,010 I will set initialToken to a variable 86 00:05:06,010 --> 00:05:10,179 and assign tokenData a token only if 87 00:05:10,179 --> 00:05:12,653 tokenData is truthy. 88 00:05:13,570 --> 00:05:16,563 And it will not be truthy if we return null here. 89 00:05:17,570 --> 00:05:20,310 If it is truthy though, we know that we have a token 90 00:05:20,310 --> 00:05:23,570 and then I'll set my initialToken to that token 91 00:05:23,570 --> 00:05:25,227 which I get from tokenData. 92 00:05:26,480 --> 00:05:28,760 Otherwise, initialToken will stay undefined 93 00:05:28,760 --> 00:05:31,713 and that will then be our initialToken state here. 94 00:05:33,410 --> 00:05:36,900 Now, if we do have tokenData and we do set a token, 95 00:05:36,900 --> 00:05:41,900 then I wanna also set my timer for that. 96 00:05:42,240 --> 00:05:44,500 And I can't do this here now, 97 00:05:44,500 --> 00:05:47,410 because I can't refer to the logoutHandler here, 98 00:05:47,410 --> 00:05:49,160 since it's only defined thereafter. 99 00:05:50,114 --> 00:05:52,414 And therefore I'll do it slightly differently. 100 00:05:53,460 --> 00:05:56,803 I will simply utilize useEffect here. 101 00:05:58,230 --> 00:06:01,170 And then maybe here after the login 102 00:06:01,170 --> 00:06:03,960 and logoutHandler functions were defined, 103 00:06:03,960 --> 00:06:05,473 I'll call useEffect. 104 00:06:06,750 --> 00:06:09,737 And here, my dependency is my tokenData. 105 00:06:10,918 --> 00:06:13,363 So that tokenData which we get here. 106 00:06:15,110 --> 00:06:18,460 And if that changes, which it should only do initially 107 00:06:18,460 --> 00:06:20,450 when this first started, 108 00:06:20,450 --> 00:06:24,210 then I'll check if tokenData is set, if it's truthy. 109 00:06:24,210 --> 00:06:27,660 And if that's the case, then I wanna repeat 110 00:06:27,660 --> 00:06:30,860 that line of code and set my timer here, 111 00:06:30,860 --> 00:06:34,063 and set it to tokenData.duration, 112 00:06:35,100 --> 00:06:37,470 that stands as time in milliseconds. 113 00:06:37,470 --> 00:06:40,500 And that should then set this logoutHandler 114 00:06:40,500 --> 00:06:43,800 to the remaining time here 115 00:06:43,800 --> 00:06:47,703 if we automatically logged in the user. 116 00:06:48,960 --> 00:06:51,880 So it should take that calculated duration 117 00:06:51,880 --> 00:06:54,213 from the storedExpirationTime. 118 00:06:56,550 --> 00:06:58,710 Now to see if that works, I'll console log 119 00:06:58,710 --> 00:07:01,690 tokenData.duration here. 120 00:07:01,690 --> 00:07:03,660 And we should therefore only see that log 121 00:07:03,660 --> 00:07:05,920 if we automatically logged the user in, 122 00:07:05,920 --> 00:07:10,253 and the duration then should also be shorter than one hour. 123 00:07:11,410 --> 00:07:13,840 So if I open my console now 124 00:07:13,840 --> 00:07:16,710 and reload here, and clear this. 125 00:07:16,710 --> 00:07:21,710 If I login here, we don't see a login console, 126 00:07:23,280 --> 00:07:25,770 but if I manually reload, we do see a log. 127 00:07:25,770 --> 00:07:29,230 And that number should be smaller every time I reload. 128 00:07:29,230 --> 00:07:31,190 And it is, because the duration 129 00:07:31,190 --> 00:07:33,800 is shorter and shorter over time. 130 00:07:33,800 --> 00:07:37,010 And since we stored a certain expiration time, 131 00:07:37,010 --> 00:07:39,730 which we can view in the Application tab here 132 00:07:39,730 --> 00:07:42,543 in the DevTools, under Local Storage. 133 00:07:43,430 --> 00:07:45,660 This is the expirationTime that was stored, 134 00:07:45,660 --> 00:07:48,760 and that's the expiration time that makes sense here for me 135 00:07:48,760 --> 00:07:51,983 when I'm recording this, that seems to work. 136 00:07:53,410 --> 00:07:56,470 Now, we can certainly restructure this code 137 00:07:56,470 --> 00:07:59,150 and reconsider this code here, 138 00:07:59,150 --> 00:08:02,550 but that's now generally working the way it should. 139 00:08:02,550 --> 00:08:06,220 We now are able to login and stay logged in 140 00:08:06,220 --> 00:08:08,600 even if we reload it. 141 00:08:08,600 --> 00:08:11,195 And of course, we can also logout 142 00:08:11,195 --> 00:08:14,300 and we automatically log the user out 143 00:08:14,300 --> 00:08:15,963 after a certain duration. 144 00:08:17,020 --> 00:08:19,420 The only remaining thing I wanna do 145 00:08:19,420 --> 00:08:21,720 is that if we do log the user out here 146 00:08:21,720 --> 00:08:25,610 in the logoutHandler, I want to also remove 147 00:08:25,610 --> 00:08:29,307 that expirationTime from localStorage. 148 00:08:30,610 --> 00:08:33,220 But with that, if I now reload, 149 00:08:33,220 --> 00:08:37,169 log back in again, like this, 150 00:08:37,169 --> 00:08:41,820 now if I have a look at my Application tab here, 151 00:08:41,820 --> 00:08:44,220 I got both pieces of data stored here, 152 00:08:44,220 --> 00:08:46,180 and if I logout, it's cleared. 153 00:08:46,180 --> 00:08:49,363 And therefore reloading now doesn't log me in automatically. 154 00:08:50,290 --> 00:08:55,290 But if I try this again and I do log back in again here, 155 00:08:57,190 --> 00:08:58,913 then this is looking good. 156 00:08:59,750 --> 00:09:03,210 And now if I try to visit /auth if I'm logged in, 157 00:09:03,210 --> 00:09:07,470 that doesn't work because of our guard here, 158 00:09:07,470 --> 00:09:12,470 where we deny access to /auth if we are logged in basically. 159 00:09:15,050 --> 00:09:17,913 And with that, that all seems to work the way it should. 160 00:09:19,320 --> 00:09:24,320 Now, one thing I wanna do here now to wrap up this logic 161 00:09:24,680 --> 00:09:27,100 regarding this useEffect call here, 162 00:09:27,100 --> 00:09:31,700 is that for one, we should also add the logoutHandler 163 00:09:31,700 --> 00:09:35,500 as a dependency here, since that is a function 164 00:09:35,500 --> 00:09:38,230 we are defining here in this component function 165 00:09:38,230 --> 00:09:40,810 in which we are using an useEffect, 166 00:09:40,810 --> 00:09:43,610 so we should add that here. 167 00:09:43,610 --> 00:09:46,750 And if we add that function, 168 00:09:46,750 --> 00:09:48,870 we should ensure that this function 169 00:09:48,870 --> 00:09:53,870 is not recreated unnecessarily to prevent infinite loops 170 00:09:54,060 --> 00:09:57,580 or unnecessary effect executions. 171 00:09:57,580 --> 00:10:00,330 And we of course learned how that works, 172 00:10:00,330 --> 00:10:03,150 we can use callback for that. 173 00:10:03,150 --> 00:10:08,150 So, here I will then just quickly import useCallback 174 00:10:09,101 --> 00:10:14,101 from React and wrap logoutHandler with useCallback, 175 00:10:16,450 --> 00:10:19,830 like this, and add my dependency array. 176 00:10:19,830 --> 00:10:23,130 And in here, we actually don't need to add anything, 177 00:10:23,130 --> 00:10:25,860 because localStorage and clearTimeout 178 00:10:25,860 --> 00:10:28,790 are browser built-in functions, 179 00:10:28,790 --> 00:10:30,950 which you don't need to add here, 180 00:10:30,950 --> 00:10:33,440 because they're not specific to your React app 181 00:10:33,440 --> 00:10:35,370 or this component function here 182 00:10:35,370 --> 00:10:37,620 in which you're having this useCallback call. 183 00:10:39,616 --> 00:10:41,820 setToken is a state updating function 184 00:10:41,820 --> 00:10:45,630 which we also don't need to add, we could add it, 185 00:10:45,630 --> 00:10:49,620 but React guarantees us that this function never changes, 186 00:10:49,620 --> 00:10:52,170 so we don't need to add it. 187 00:10:52,170 --> 00:10:55,790 And logoutTimer is a global variable, 188 00:10:55,790 --> 00:11:00,790 which also is outside of that React rendering flow 189 00:11:01,000 --> 00:11:04,080 and therefore also doesn't need to be added here. 190 00:11:04,080 --> 00:11:08,203 So this is how we can define the logoutHandler now. 15261

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.