We wrote some initial code to fetch
the reviews from the Strapi API.
But at the moment we're getting a lot
of data we don't actually need,
like all the different image formats.
There is a way to select only specific fields.
If we look at the Strapi documentation,
it provides a feature called "Field selection".
When calling the API we can specify
which fields we want
by adding some parameters with the field names
like, in this case, "title" and "body".
Now, this query string in the URL
is a way of encoding an array.
It's easier to understand if we
look at the JavaScript example.
We can specify an array of "fields",
and that array is then encoded in
the URL using the "qs" library.
So we'll want to use that library in our project.
Let's go and add it to our dependencies.
In the Terminal I'll run "npm install qs"
and this will download the right package.
Now let's see how to use it in our code.
First of all we want to import "qs"
from the module with the same name.
And then we can use it to encode the
parameters we append to the URL.
We want to call "qs.stringify"
passing an object with the Strapi parameters,
but we also need a second object
where to specify options.
Here we need to set "encodeValuesOnly" to "true",
which means it will not encode the parameter names,
only their values.
Anyway, among the API parameters
we can set a "fields" array,
listing which properties we want, like
"slug" and "title" for example.
Let me log the "url" to the console, so
you can see what the "qs" library does.
If we save, and go and run our
"strapi-request" script,
you can see that the data in the response only
contains "slug" and "title" attributes.
And you can also see how the "qs"
library encoded the array:
the first element is written as "fields"
with zero inside square brackets,
and the second element is "fields" at index 1.
This is how the "qs" library converts
an array into multiple parameters.
We don't need to worry too much about the details,
we can just set the options in JavaScript,
and the "qs" library will take
care of encoding them.
Now, let me request all the fields again,
including populating the relations,
so we can see all the available
fields in the response.
And we can then decide which ones to select,
based on how we're going to use the data.
When reading local files we were
returning these properties.
We don't actually need the "body"
when listing the reviews,
it's only used when displaying a specific review.
So when calling the API we certainly
want "slug" and "title".
Now, the CMS data also includes a "subtitle";
let's add that field as well, even though
we're not currently using it.
It will be useful later on.
Next, we need a "date".
But there isn't a "date" property
in the CMS response.
There is however a field called "publishedAt",
that is the date and time of when
the entry was published.
So we can use that field as the review date.
And then we need the "image",
which is a bit more complex because
it's a nested object.
All we need in our application
is actually the image "url".
So we want to select only that field.
We can do that by changing the "populate"
parameter to be an object,
where we can include the "image" relation.
And here we can pass options for this relation,
like which "fields" to select.
If we put "url" in this array, it
should only return that property.
Let's save, and test if it works.
You can see that, for each element
in the "data" array,
it only returned the "attributes" we requested.
And the "image" data only includes
the "url" attribute.
So this makes the response a lot smaller,
which means the API request
should be faster as well.
Now, in addition to the "data" array,
the response also contains a "meta" object,
with some "pagination" values.
By default, Strapi uses 25 as the "pageSize".
This means it will return at most 25 entries.
As it happens, there are exactly
25 entries in total,
but that's just a coincidence.
We should really specify the "pageSize"
explicitly when making the request,
rather than relying on whatever the default is.
So we can add a "pagination" parameter,
setting the "pageSize" to
let's say we only want 6 reviews initially.
That's enoughÂ to display on the Reviews page.
We can also pass a "page" number,
but we'll implement full pagination
in another section.
For now we can just fetch a
fixed number of reviews.
You can see that "pageSize" is now 6,
so, even though there are 25 entries in total,
this response will only contain the first 6.
Now, the last thing we want
to do is sort the reviews.
If you remember, in our existing pages
we sorted them by most recent first.
While this data is currently
sorted by "id" I think.
Certainly not by date,
because the first entry was published on May 16th,
while, if we scroll to the second entry,
this one has May 9th,
which is actually older,
but the third one is May 18th,
that's more recent than the first two.
And the next one is somewhere in the middle.
I set the dates when preparing this data
making sure every review is published
on a different day.
Anyway, in our request parameters
we can set a "sort" option,
that must be an array listing which
fields to use for sorting,
so here we want "publishedAt".
But we also want to append ":desc",
that's short for "descending",
which in this case means reverse
chronological order.
Let's see if this works as expected.
The first review is now the
one published on May 28th.
Let's check the second one.
This says May 27th,
that is the day before.
Then we have May 26th,
that is again a day earlier,
so looks like they're in the right order.
And with this, we now have all the data we need
to display the ReviewsPage in our website.
In the next video we'll update our main
application code to do exactly that.