Accessing items of a collection from a custom panel in Directus
In a previous post I showed you how to create a custom panel for your insights on Directus. Since it was a simple example I used hardcode data for the chart. Of course in a real application you can’t use hardcode information even if you’re really fast updating the content.
TL;DR
If you are already a directus expert you can clone the full code of this post here
Running our dev command to compile our panel on every change
So let’s update our custom extension to use data from a directus collections instead just hardcode data. Before starting let’s run the dev command:
1 | cd piechart-panel |
Accessing the collection from a vue component
For this example I’m going to create a user collection with 3 fields: id, name and country.
And now I’m going to import from a csv file with some data for our collection
Let’s open our panel.vue file and add the code that allow fetching the data from the user collection.
Since our component is just part of a whole Vue application directus already include a provider for accessing the API. The provider is called api.
1 | export default defineComponent({ |
now we have the api object in our instance, let’s add the code to make the http request and get the information from the user collection. We’re going to do this in the mounted function.
1 | export default defineComponent({ |
directus already provide documentation for accessing the items of a collection. For our example the url have the segments:
- /items - because we’re trying to get items of a collection
- /user - because that’s the name of the collection (can be anything you want at the moment of creating it)
- ?aggregate[count]=id&groupBy[]=country - since we need the total of users per country this is similar to writing a sql query like this:
1 | select count(id) from users group by country; |
You can learn more about Aggregation & Grouping filters in this link.
After all of this we’re just logging the response to the console so we can check the structure:
ok since directus use axios under the hood it’s a very familiar structure (at least for me a former axios fanboy) we have a data object and inside of it a data array that includes all the items from the user colecction group by country.
Let’s back a little bit and remember what’s the data structure that chartjs needs:
1 | chartData: { |
In order to make chartjs happy we can iterate the results in the response and in each iteration we can push the name of the country to the labels array and then get the total users per country from the count object.
1 | mounted() { |
we’re almost done, the last thing to do is deal with the async nature of the operation, at the beginning the component is not going to have any data until the api send a response, so let’s add a quick loading message while the request is in progress and only show the chart until the response is ready.
Our template is gonna change a bit:
1 | <template> |
We’re using a showChart variable that is going to start with a false value and once the request has finished we change the value to true.
Of course the showChart variable needs to be declared in our data inside the definition of the component
1 | export default defineComponent({ |
Ok we’re ready to give it a try, let’s restart our container
1 | docker-compose restart |
and now we can see the final result, our chartjs custom panel using information from a directus collection
That’s it! Pretty simple to interact with the API and get information from a collection. Here’s the full code for the panel.vue file.
1 | <template> |
Would be great if the users of the admin could have the possibility of choosing a collection and not be restricted to just the user collection like in this demo, but that’s for a future post.
Full code on github
Hope this post help you!