5

I recently started working with strapi and have been figuring out how to go about content relations and so on... Now I have reached a point when I have multiple content relations dependent on each other.

This is my strucute:

Collection Types:

  1. Categories
  2. Articles
    • with content relation: Article has one category

Single Types:

  1. Homepage
    • with content relation: Homepage has many articles

Now what I want to do is to to get all nested properties of a category for articles that are assigned to homepage just by simply making a GET request from /homepage

What I currently get is a json structure like this:

{
   "id": 1,
   "hero": {
    ....
   },
   "featuredArticles": {
    ....
   },
   "displayedArticles": [
      {
         "id": 2,
         "category": 5,
      }
   ]
}

What is the expected output:

{
   "id": 1,
   "hero": {
    ....
   },
   "featuredArticles": {
    ....
   },
   "displayedArticles": [
      {
         "id": 2,
         "category": [
            {
              "id": 5,
              "title": "Foundation"
            }
         ],
      }
   ]
}

My suspicion is that the properties of categories is basically too nested when trying to fetching from /homepage rather than /articles directly.

I found out that handling this could work with modifying the controllers right in the strapi directory but I haven't figured it out quite.

Strapi Controller Docs

Is here anybody who knows solution to this?

Adam Schwarcz
  • 437
  • 1
  • 4
  • 14

2 Answers2

2

In Strapi v4 you can retrieve deeply nested relations at request time, I had to retrieve a nested relation category_tags that was related to categories which was a relation to the page collection type I was trying to retrieve. Here is a link for more information https://docs.strapi.io/dev-docs/api/rest/populate-select

As an example, this call only retrieved the categories relation from the page collection type, but I needed the category_tags relation from categories aswell.

{{dev_url}}/api/pages?populate=*

This call will retrieve the nested relation category_tags from categories when retrieving the page collection type.

{{dev_url}}/api/pages?populate[categories][populate][0]=category_tags

To add to this, I also needed to retrieve another relation from within category_tags called feature and get back an image, so now I need to get data three levels deep.

{{dev_url}}/api/pages?populate[categories][populate][category_tags][populate][feature][populate][0]=category_tag,cover

This part specifically [0]=category_tag,cover is retrieving the category_tag and cover image from feature.

BerenBoden
  • 41
  • 5
0

Firstly you'll need a custom controller function for this. In /api/homepage/controllers/homepage.js you can export your custom find function.

There you can define which fields you want to populate:

module.exports = {
 find: ctx => {
   return strapi.query('homepage').find(ctx.query, [
     {
       path: 'displayedArticles',
       populate: {
         path: 'category',
       },
     },
   ]);
 }
};

For reference see the most recent beta docs: Customization

Second way: populate it as per requirement

module.exports = {
  find: async (ctx) => {
    const homePage = await strapi.query('homepage').find(ctx.query);
    const categories = await strapi.query('categories').find();

    if (homePage[0].displayedArticles) {
       homePage[0].displayedArticles.forEach(async (content) => {
         if(categories){
           content.category = categories.find((category) => {
             return category.id === content.category;
           });
         }
      });
    } 
    
    if (homePage[0].displayedComponents) {
      homePage[0].displayedComponents.forEach(async (content) => {
        if(categories){
         content.category = categories.find((category) => {
           return category.id === content.category;
          });
        }
      });
    } 
    
    return homePage;
  }

};
Amit Rahav
  • 115
  • 1
  • 15
Anuj Divkar
  • 252
  • 1
  • 10
  • What this does to me is that it reduces the response from /homepage significantly. Nor it populates the category, nor it shows the data that were in the response by default. – Adam Schwarcz Apr 14 '21 at 14:50
  • I get something like 40% of the data that were in the response originally. "displayedArticles" doesn't show at all. – Adam Schwarcz Apr 14 '21 at 14:51
  • @AdamSchwarcz I have edited my answer with alternate way. Kindly test it. – Anuj Divkar Apr 14 '21 at 16:19
  • {"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"} this is what is get – Adam Schwarcz Apr 14 '21 at 16:28
  • Usually what I find in articles is that when someone needs help with population they're stuck with getting a response of `category: {...}` (the unpopulated object clearly indicates there is something to poipulate) but my problem is that the category show only `category: 5` (only the ID, nothing else and doesnt show unpopulated object inside) for some reason. It is a deeply nested relation - homepage has many articles while each article has one category = that categories are pulled from the articles not the homepage itself – Adam Schwarcz Apr 14 '21 at 16:32
  • @AdamSchwarcz can you contact me on skype anujdivkar may be I can help you over skype.My email anuj.r.divkar@gmail.com – Anuj Divkar Apr 14 '21 at 16:48
  • const categories = await strapi.services['category'].find(); I had used categories ealier. kindly correct it and test – Anuj Divkar Apr 14 '21 at 16:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/231135/discussion-between-anuj-divkar-and-adam-schwarcz). – Anuj Divkar Apr 14 '21 at 16:56