Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
With our app complete, there are parts of our code that we can refactor to minimize duplicate code. In this step, we'll create the api helper function that will make our fetch calls.
Resources
Treehouse Courses and Workshops
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
There's one more refactoring
I would like to do with you.
0:00
In our app, whenever we need to
communicate with the server,
0:03
we will need to call the fetch method and
generate the options object.
0:07
Currently, our app only
makes two fetch calls.
0:12
But imagine if we turned our
app into an online store.
0:16
We would need to make
multiple fetch calls.
0:20
One to get a list of products,
one to get the product details,
0:23
one to let the server know that
the user bought some products.
0:26
You get the point.
0:30
Having to create an options object over
and over again can become tedious.
0:31
Instead, we'll create a helper
function that generates
0:37
the options object and
calls the fetch method for us.
0:42
We'll start off by creating a new
folder in source called utils,
0:46
which is short for utility.
0:52
This folder will contain
our helper function.
0:54
So let's add a new file
called apiHelper.js.
0:58
Or name our helper function api,
1:04
since this function's job will be
to make fetch calls to our API.
1:07
Let's not forget to export it so
1:12
that we're able to use this
function in our components.
1:15
We'll use the fetch calls we've
written earlier as a reference to help
1:19
us build our API function.
1:24
In UserSignUp, we'll copy
fetchOptions and the fetch call.
1:25
Under our api function,
I'll create a multi-line comment
1:33
with /* */.
1:38
I'll title this Create User,
and paste the code underneath.
1:42
In UserContext, let's copy over
1:48
encodedCredentials, fetchOptions and
the fetch call.
1:52
Back in apiHelper, I'll create another
multi-line comment with the title,
1:57
Get Auth User, and
paste the code underneath.
2:04
To make any fetch calls,
2:11
the api function will need to know
the URL and the fetch method.
2:14
So let's add them as parameters.
2:19
To create a new user, we'll need
to provide our fetch method a body
2:23
containing the user's info,
and to authenticate a user,
2:28
we'll need to send the user's credentials.
2:32
So let's add body and
credentials as parameters.
2:36
For this project,
when making any fetch calls to our API,
2:42
the URL will always start
with localhost:5000/api.
2:48
So instead of having to pass
the entire URL to our API function,
2:54
we can just pass the URL path,
in both cases, /users.
3:01
So we'll rename the URL parameter to path,
and create a URL variable.
3:07
url will contain the URL
to make the fetch call too.
3:14
So we'll set it equal to
http://localhost:5000/api,
3:19
plus the path parameter.
3:26
Next, we'll create fetch's options object,
and name it options.
3:31
Both of our fetch options
objects contain the method and
3:40
header's properties, so
we'll add those to the object.
3:45
Firstly, we'll add the method property and
set its value to the method parameter.
3:49
Since the property and value have the same
name, we can simply write method.
3:55
Next, let's add a header's property and
set its value to an empty object.
4:02
The header we provide depends on what
we're sending in the fetch method.
4:09
For example, when we create a new user,
we add the user's info to body and
4:15
add the Content-Type header
to indicate the body type.
4:21
Or when we authenticate a user,
we'll need to send
4:26
the encoded credentials in
the Authorization header.
4:30
So we'll leave header's value to an empty
object and add the headers when needed.
4:35
We'll now handle sending
data to our fetch calls.
4:41
We'll first add an if statement to check
if the body parameter was provided.
4:45
If so, we'll add the body property
to options with options.body
4:50
and set it equal to the stringified
body with JSON.stringified(body).
4:58
Since the fetch call will contain a body,
5:06
we'll need to add the content
type header to options.
5:09
To do so,
we'll type options.headers["Content-Type"],
5:13
and I'll copy over its value.
5:19
We had to use the bracket notation
here instead of the dot notation
5:29
because the header name,
Content-Type is a string.
5:34
Lastly, we'll check if credentials needs
to be provided to the fetch call by adding
5:38
an if statement that checks if credentials
was provided to the api function.
5:45
If the credentials parameter was provided,
we'll encode the credentials
5:51
by copying over the base64
encoding from the comments below.
5:56
We'll provide the encoded
credentials to options
6:04
header with options.headers.Authorization,
and
6:09
setting it equal with
a template literal with Basic,
6:14
and passing it the encodedCredentials.
6:19
Great, we handled adding a body and
6:23
credentials to our fetch
calls when needed.
6:25
Lastly, our api function will return
6:29
the fetch method taking in url and
options.
6:34
The final touches I like to give
to my helper functions are adding
6:39
default values for optional parameters.
6:44
We'll leave our path parameter required
since we need it to create the URL.
6:49
We'll set method's default value to GET,
6:54
since it's also fetch's default method.
6:59
If the body parameter wasn't included,
7:02
we'll set the default value to null,
and do the same for credentials.
7:05
Our API helper function is now ready
to be used throughout our app.
7:11
I'll go ahead and clean up the file
by deleting the comments below.
7:16
In the UserSignUp component,
7:21
let's import our api function with
7:25
import { api } from '../utils/apiHelper'.
7:29
We'll scroll down and
delete fetchOptions as well as
7:35
replace the fetch call
with our api function.
7:39
The first argument is the URL path, so
7:44
we'll pass /users, as a string.
7:49
The second argument is the method,
which will be post.
7:53
And lastly, we'll provide the data
that should be included in the body,
7:58
which is the user variable.
8:04
Let's save our changes and
make sure we're still able to sign up.
8:06
Head over to the signup route.
8:11
Submit an empty form and
the errors still display.
8:15
Let's complete the form and click Sign Up,
8:19
and we've been signed in, great.
8:25
Our API helper function is
successfully calling the fetch method
8:28
to sign a user up.
8:32
Let's now use it to authenticate a user.
8:34
In the UserContext file,
8:38
we'll import the api function with
8:41
import { api } from '../utils/apiHelper'.
8:46
In the signIn function, we can now delete
encodedCredentials and fetchOptions.
8:52
We'll replace our fetch
method with api and
9:00
pass it the path, /users,
and the method, GET.
9:05
Since we don't need to include
a body to our fetch call,
9:11
we'll set the third argument to null.
9:15
And lastly,
we'll pass it the user's credentials.
9:18
Let's save and
make sure we can still sign in.
9:22
Over in the browser, I'll sign out and
try to sign back in.
9:26
And I was able to.
9:33
We can now use our API helper function
anywhere in our app instead of
9:35
calling the fetch method.
9:40
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up