Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,090 --> 00:00:04,930
So I now wanna get rid here of DUMMY_MEALS
2
00:00:04,930 --> 00:00:07,490
and instead fetch data from Firebase,
3
00:00:07,490 --> 00:00:09,610
and we learned how that works.
4
00:00:09,610 --> 00:00:13,260
For this, we can use the built-in fetch API,
5
00:00:13,260 --> 00:00:15,240
which is built into the browser.
6
00:00:15,240 --> 00:00:19,360
So this fetch function exists out of the box.
7
00:00:19,360 --> 00:00:23,610
We could also use a custom HTTP hook,
8
00:00:23,610 --> 00:00:27,080
for example, the one which we built in the HTTP section,
9
00:00:27,080 --> 00:00:29,890
but here I will build it from scratch again.
10
00:00:29,890 --> 00:00:31,810
Though, if you wanna use a custom hook,
11
00:00:31,810 --> 00:00:33,610
or wanna build a custom hook,
12
00:00:33,610 --> 00:00:37,300
or use some third-party HTTP hook package,
13
00:00:37,300 --> 00:00:39,990
that would, of course, also be okay.
14
00:00:39,990 --> 00:00:41,550
But I wanna build it from scratch here,
15
00:00:41,550 --> 00:00:45,750
so I'll use, I'll write the fetch function from scratch,
16
00:00:45,750 --> 00:00:48,460
and I want to fetch my meals data
17
00:00:48,460 --> 00:00:51,740
when this component is loaded.
18
00:00:51,740 --> 00:00:52,573
And we learned
19
00:00:52,573 --> 00:00:56,220
that we can utilize the useEffect hook for this.
20
00:00:56,220 --> 00:00:59,570
So we can import useEffect from react
21
00:00:59,570 --> 00:01:04,030
to trigger a side effect like fetching data from the web
22
00:01:04,030 --> 00:01:06,140
when some data changes
23
00:01:06,140 --> 00:01:08,820
or, for example, when that component is loaded
24
00:01:08,820 --> 00:01:11,020
for the first time.
25
00:01:11,020 --> 00:01:12,747
So here I'll set up useEffect
26
00:01:12,747 --> 00:01:16,420
and the effect function that should be triggered.
27
00:01:16,420 --> 00:01:19,583
And then in there we can call fetch, like this.
28
00:01:20,530 --> 00:01:23,510
Now, here we wanna send an HTTP request
29
00:01:23,510 --> 00:01:26,500
to this meals node here,
30
00:01:26,500 --> 00:01:31,410
so to this Firebase URL and then this meals node.
31
00:01:31,410 --> 00:01:34,990
So the full URL is this Firebase URL,
32
00:01:34,990 --> 00:01:38,507
which I grabbed here, and then meals.json.
33
00:01:38,507 --> 00:01:43,093
.json is something Firebase-specific which we have to add.
34
00:01:44,570 --> 00:01:46,520
So with that, we're sending a request
35
00:01:46,520 --> 00:01:51,450
to this REST API endpoint, which Firebase exposes here,
36
00:01:51,450 --> 00:01:54,340
and we're sending this request to fetch the meals.
37
00:01:54,340 --> 00:01:57,100
We could configure this request, as you learned,
38
00:01:57,100 --> 00:02:00,090
with a second argument passed to fetch,
39
00:02:00,090 --> 00:02:01,700
but there we could, for example,
40
00:02:01,700 --> 00:02:03,950
change the HTTP method and so on,
41
00:02:03,950 --> 00:02:05,870
and we don't really wanna do that here.
42
00:02:05,870 --> 00:02:10,423
We wanna stick to the default GET request, so this is fine.
43
00:02:11,640 --> 00:02:14,030
Now, fetch returns a promise
44
00:02:14,030 --> 00:02:19,030
since sending such a HTTP request is an asynchronous task.
45
00:02:19,290 --> 00:02:21,640
Hence, we can add then here
46
00:02:21,640 --> 00:02:25,810
to provide a function, this function here,
47
00:02:25,810 --> 00:02:28,870
which is triggered when the request is done,
48
00:02:28,870 --> 00:02:30,880
once we got a response.
49
00:02:30,880 --> 00:02:33,390
Or we use async await.
50
00:02:33,390 --> 00:02:36,770
For this, we need to turn this into async function
51
00:02:36,770 --> 00:02:39,420
so that we can use the await keyword here.
52
00:02:39,420 --> 00:02:41,790
But here we have to be careful,
53
00:02:41,790 --> 00:02:44,610
and, actually, we even get a warning here.
54
00:02:44,610 --> 00:02:47,823
At least, you might get one depending on your project setup.
55
00:02:48,660 --> 00:02:51,600
The function you pass to useEffect
56
00:02:51,600 --> 00:02:54,460
should not return a promise.
57
00:02:54,460 --> 00:02:56,500
Instead, you learned that the function
58
00:02:56,500 --> 00:02:58,180
you pass to useEffect
59
00:02:58,180 --> 00:03:02,113
may return a cleanup function which can be executed.
60
00:03:02,950 --> 00:03:04,860
You learned about that in the module
61
00:03:04,860 --> 00:03:06,910
where I introduced useEffect.
62
00:03:06,910 --> 00:03:10,530
That cleanup function should run synchronously though.
63
00:03:10,530 --> 00:03:13,890
It should not return a promise or anything like this.
64
00:03:13,890 --> 00:03:17,440
Hence, this overall function which we pass to useEffect
65
00:03:17,440 --> 00:03:21,400
must not be turned into an async function.
66
00:03:21,400 --> 00:03:25,270
Instead, if you wanna use async await instead of useEffect,
67
00:03:25,270 --> 00:03:29,270
simply create a new function here, fetchMeals, like this,
68
00:03:31,720 --> 00:03:36,030
and use async here and put your code, this line of code,
69
00:03:36,030 --> 00:03:39,450
into this nested inner function,
70
00:03:39,450 --> 00:03:43,043
and then just execute fetchMeals as part of useEffect.
71
00:03:44,030 --> 00:03:47,680
By doing it that way, this function is still executed,
72
00:03:47,680 --> 00:03:49,880
and you can still use async await,
73
00:03:49,880 --> 00:03:52,130
but the overall useEffect function
74
00:03:52,130 --> 00:03:54,290
does now not return a promise.
75
00:03:54,290 --> 00:03:56,320
It's now not an async function
76
00:03:56,320 --> 00:03:58,660
because we have not added async here,
77
00:03:58,660 --> 00:04:00,530
which would not be allowed.
78
00:04:00,530 --> 00:04:03,810
So that's a little workaround around that restriction,
79
00:04:03,810 --> 00:04:05,563
which is absolutely fine though.
80
00:04:06,620 --> 00:04:08,860
So now with that, we can use async await
81
00:04:08,860 --> 00:04:12,903
to get a response here for fetching our meals.
82
00:04:13,810 --> 00:04:16,990
And then you learned that for fetch, we can parse data.
83
00:04:16,990 --> 00:04:18,533
We get our response,
84
00:04:19,740 --> 00:04:20,740
responseData
85
00:04:22,100 --> 00:04:25,093
by calling response.json,
86
00:04:25,950 --> 00:04:27,610
which also returns a promise,
87
00:04:27,610 --> 00:04:30,023
hence we also have the await keyword here.
88
00:04:30,940 --> 00:04:33,490
So that's how we can get the responseData
89
00:04:33,490 --> 00:04:34,390
which we're fetching,
90
00:04:34,390 --> 00:04:36,503
and then we can utilize that responseData.
91
00:04:37,340 --> 00:04:41,150
Now, the responseData we're getting in the case of Firebase,
92
00:04:41,150 --> 00:04:44,240
and that's something Firebase-specific,
93
00:04:44,240 --> 00:04:47,320
will always be an object where these ids here,
94
00:04:47,320 --> 00:04:50,360
m1, m2, m3, m4,
95
00:04:50,360 --> 00:04:51,960
will be keys,
96
00:04:51,960 --> 00:04:55,600
and then the values for those keys will be nested objects
97
00:04:55,600 --> 00:04:57,373
with those properties.
98
00:04:58,370 --> 00:05:00,020
Hence, what we get back here,
99
00:05:00,020 --> 00:05:04,420
responseData will be an object, and I want an array,
100
00:05:04,420 --> 00:05:06,910
therefore we need to transform this.
101
00:05:06,910 --> 00:05:11,273
So we can create a new constant loadedMeals,
102
00:05:12,420 --> 00:05:14,130
which is an empty array,
103
00:05:14,130 --> 00:05:16,160
and then we use a for/in loop
104
00:05:16,160 --> 00:05:20,100
to go through all the keys in responseData,
105
00:05:20,100 --> 00:05:22,763
so in this responseData object.
106
00:05:24,370 --> 00:05:26,980
And the keys will be these ids here,
107
00:05:26,980 --> 00:05:28,590
and the values for those keys
108
00:05:28,590 --> 00:05:31,393
will then be the nested objects, as I just explained.
109
00:05:32,240 --> 00:05:35,280
So here we then wanna reach out to loadedMeals
110
00:05:35,280 --> 00:05:39,570
and push a new object into this initially empty array
111
00:05:40,460 --> 00:05:44,090
where we, for example, set the id property.
112
00:05:44,090 --> 00:05:45,850
We need to set id here
113
00:05:45,850 --> 00:05:49,520
because we do expect our meals to have an id field.
114
00:05:49,520 --> 00:05:52,710
So we should make sure that we transform the loaded data
115
00:05:52,710 --> 00:05:55,710
such that we do have an id field.
116
00:05:55,710 --> 00:05:57,980
And then we can set id equal to key
117
00:05:57,980 --> 00:06:02,050
because, as I just mentioned, the key will be the id
118
00:06:02,050 --> 00:06:04,673
of the individual meals we're fetching.
119
00:06:06,840 --> 00:06:09,260
Now, we also need to set a name,
120
00:06:09,260 --> 00:06:11,260
the description, and price fields.
121
00:06:11,260 --> 00:06:15,100
And name can be pulled out of the responseData
122
00:06:15,100 --> 00:06:17,460
for the given key.
123
00:06:17,460 --> 00:06:20,700
With that, we access the nested object in there.
124
00:06:20,700 --> 00:06:23,920
And then that nested object will have a name field,
125
00:06:23,920 --> 00:06:25,760
as I just show you.
126
00:06:25,760 --> 00:06:26,940
We're now accessing
127
00:06:26,940 --> 00:06:29,513
this nested name field here, for example.
128
00:06:31,090 --> 00:06:33,230
And we don't just do that for the name.
129
00:06:33,230 --> 00:06:36,840
We also replicate this for the description here
130
00:06:37,970 --> 00:06:42,770
and then also one more time for the price, like that.
131
00:06:45,200 --> 00:06:48,720
With that, we're transforming the fetched data.
132
00:06:48,720 --> 00:06:52,270
Now, we need to expose that fetched data
133
00:06:52,270 --> 00:06:54,850
to, well, to the rest of our component,
134
00:06:54,850 --> 00:06:56,760
and we wanna re-render the component
135
00:06:56,760 --> 00:06:58,450
once the fetching is done
136
00:06:58,450 --> 00:07:02,100
because that's an asynchronous task, which is only started
137
00:07:02,100 --> 00:07:04,510
after the component loaded for the first time,
138
00:07:04,510 --> 00:07:07,240
and therefore, initially, there will be no data,
139
00:07:07,240 --> 00:07:10,570
and we wanna update the component once the data is there.
140
00:07:10,570 --> 00:07:12,790
Now, when we have data that changes
141
00:07:12,790 --> 00:07:16,020
and where a component should be re-evaluated
142
00:07:16,020 --> 00:07:17,490
once it did change,
143
00:07:17,490 --> 00:07:21,790
whenever we have a use case like this, we need state.
144
00:07:21,790 --> 00:07:26,330
So we should also import useState here from react
145
00:07:26,330 --> 00:07:28,720
and then set up some state in this component
146
00:07:28,720 --> 00:07:29,753
by calling useState.
147
00:07:30,810 --> 00:07:33,700
And here we initially might have an empty array
148
00:07:33,700 --> 00:07:37,410
because this state will be our meals
149
00:07:37,410 --> 00:07:40,363
and the setMeals state-updating function.
150
00:07:41,400 --> 00:07:43,910
It's now the meals which I wanna use down there
151
00:07:43,910 --> 00:07:47,580
instead of DUMMY_MEALS to render the MealItems.
152
00:07:47,580 --> 00:07:49,370
And initially, that's an empty array, again,
153
00:07:49,370 --> 00:07:52,830
but that will change once the loaded data is there.
154
00:07:52,830 --> 00:07:55,800
And therefore, here, after this for loop,
155
00:07:55,800 --> 00:07:59,770
once we filled our loadedMeals helper constant here
156
00:07:59,770 --> 00:08:03,704
with the transformed data, I wanna call setMeals.
157
00:08:03,704 --> 00:08:06,290
So I wanna call that state-updating function
158
00:08:06,290 --> 00:08:08,550
and pass in the loadedMeals,
159
00:08:08,550 --> 00:08:11,900
so that array which we populated here.
160
00:08:11,900 --> 00:08:13,520
With that, we're setting the data,
161
00:08:13,520 --> 00:08:17,550
and therefore then this component should update.
162
00:08:17,550 --> 00:08:20,080
Now, for this useEffect function here,
163
00:08:20,080 --> 00:08:23,360
currently our dependency array is an empty array.
164
00:08:23,360 --> 00:08:25,060
So we have no dependencies,
165
00:08:25,060 --> 00:08:28,720
which means this useEffect function, this function here,
166
00:08:28,720 --> 00:08:32,559
will only run when the component was first loaded.
167
00:08:32,559 --> 00:08:35,179
It will never run again thereafter.
168
00:08:35,179 --> 00:08:37,350
And that sounds about right to me.
169
00:08:37,350 --> 00:08:40,179
We, indeed, have no dependencies in there,
170
00:08:40,179 --> 00:08:44,230
we're not using any external component-specific data,
171
00:08:44,230 --> 00:08:47,790
we're not using any props in there or anything like that,
172
00:08:47,790 --> 00:08:49,710
and therefore only running this
173
00:08:49,710 --> 00:08:53,250
when the component is first loaded makes a lot of sense,
174
00:08:53,250 --> 00:08:56,123
so we don't need to change this dependency's array.
175
00:08:57,740 --> 00:08:59,130
And therefore, with all of that,
176
00:08:59,130 --> 00:09:03,770
if we save this, we go back to our project, if I reload,
177
00:09:03,770 --> 00:09:06,440
you see initially that list is empty,
178
00:09:06,440 --> 00:09:09,350
but then the data arrives quickly.
179
00:09:09,350 --> 00:09:12,810
Now, of course, we can show some loading spinner
180
00:09:12,810 --> 00:09:15,530
or some loading state instead if we want to,
181
00:09:15,530 --> 00:09:17,130
though currently the experience
182
00:09:17,130 --> 00:09:19,410
also isn't too bad, I would argue,
183
00:09:19,410 --> 00:09:21,720
but still, handling a loading state
184
00:09:21,720 --> 00:09:23,660
and a potential error state
185
00:09:23,660 --> 00:09:26,063
is something we're going to dive in next.
14684
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.