We rewrote the "getReview" function
so that it fetches the data from Strapi.
And before that we did the same for "getReviews".
Now, there's a fair amount of duplication
between these two functions,
so in this video I want to do some refactoring,
and extract the common code
into a separate function.
Let's start by copying the full "getReviews" code,
but this should be an internal function,
that's not exported,
and we could call it "fetchReviews",
since it will contain the common fetch code.
This function could return the JSON response,
because how to extract the data
will be different in each case.
We could also accept the "parameters"
as an argument,
so we can use this function to make different requests,
with different options.
We always fetch the same endpoint,
but with different parameters,
and we'll handle the response data differently.
Let me also update the log statement,
to print the right function name.
Ok, I think this should work.
We can now call "fetchReviews" instead of
repeating all the steps in each function.
So here we can get the "data"
by calling our new function,
and passing the same object
with the API parameters.
But at this point we can remove
a few lines of code.
We no longer need to know which URL to call here,
or how to encode the parameters.
Let's save and check that the
Reviews page still works.
Ok, now we can update "getReview" as well.
Let's do the same thing and call "fetchReviews"
to get the response,
passing the same Strapi parameters as before.
And now we can remove the old code.
Let's save, and test if an individual
Review page works.
It's all good.
So, both these functions now call "fetchReviews",
which makes it easier to modify
the common request code.
One thing we should do, whenever
we make an HTTP request
is check if the response was "ok",
because the server could return an error,
like 404 Not Found for example.
In this case we should really throw our own Error
so we can provide a useful error message.
We could include the "response.status",
like "404" if the resource doesn't exist,
and also show which "url" we tried to request.
This way, if there is an error,
at least we can more easily tellÂ
what caused the problem.
And we don't have to duplicate the same
error checking code everywhere.
Now, there's still some duplication
between these two functions,
in the code that converts the
data returned by the CMS
into our own objects, with only
the properties we want.
"getReview" is a bit different,
because we also have the "body" here.
But we should still be able to extract the
logic for all the other properties.
Let's go and create another function,
we can call it "toReview".
It will take an "item" as returned by the CMS
and convert it into our custom object,
extracting the right properties
from the CMS "attributes".
In fact, we need to define "attributes" here;
I'll do that by destructuring the "item" object.
This way, when calling "toReview",
we can pass a full CMS object.
So, if we start from "getReviews",
we can simply pass our new function
to the "map" method.
For each element in the "data"
array we call "toReview"
converting it to our own object type.
Let's reload the Reviews page, to
prove that it's still working.
Ok. At this point we can update
"getReview" as well.
In this case however, we can only
replace these common properties,
while still adding the "body" separately.
What we can do is call "toReview"
but then expand its properties,
using "dot dot dot" that is the
JavaScript "spread syntax".
Now, we need to pass it the "item" object
that is the first element in the "data" array.
And if we do this we also need to
write "item.attributes" here.
Ok, I think this should work,
if we try opening a Review page.
That's it. We just did some refactoring,
and simplified these two functions
by extracting the common logic into
separate shared functions.
This will also make it easier to
write additional API requests.
And in fact in the next video we'll reimplement
the "getSlugs" function.