Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Query nested object more than 2 depth if they have relations #87

Closed
gengengengengen opened this issue Nov 5, 2019 · 7 comments
Closed

Comments

@gengengengengen
Copy link

gengengengengen commented Nov 5, 2019

Hi, please forgive my pool English.

I want to use gatsby-source-strapi to query objects with relations in one single graqhql query.

I added 3 contents and set relations in Strapi, but in Gatsby I still cannot query nested objects more than 2 depth like:

 query MyQuery {
            allStrapiObject_1 {
                edges {
                    node {
                        obj_1_props,
                         ...
                        obj_2_related_to_obj_1 {
                                obj_2_props,
                                 ...
                                obj_3_related_to_obj_2 {   // Cannot be found in field 'obj_2'
                                    obj_3_props
                                    ...
                                }
                        }
                    }
                }
            }
        }

I can only query the 'obj_2' in 'obj_1', but 'obj_3' cannot be query. Is there any way to get the nested data more than 3 depth?

@javery014
Copy link

I came across this issue while experiencing the same issue of deep relations not being included in my queries. After a day of research, I finally found the solution that worked for me, and might work for anyone who has a problem similar to what this issue describes.

I have a content type blog-index, representing the index page of our blog site. I a couple relations on that content type: top_post and featured. These relations point to my blog content type. My blog content type then has a many to many relation with blog-tag. blog-tag was not getting populated in the blog data retrieved from top-level blog-index.

My fix was to customize the find controller of blog-index to specifically include relations:

async find(ctx) {
    const entity = await strapi.services['blog-index'].find(['featured.blog_tags', 'featured.image', 'top_post.blog_tags', 'top_post.image', 'trending']);
    return sanitizeEntity(entity, { model: strapi.models['blog-index'] });
  },

My hypothesis is Strapi controllers don't include deep many to many relations by default in queries. You have to explicitly include them. But then, once you explicitly include a relation, you need to explicitly include all relations you want.

Once I modified my blog-index find controller, gatsby-source-strapi picked up on the deep relations just fine. Hopefully this helps others who might end up on this issue in their search for a solution.

@jimsheen
Copy link

This solution worked for me. I have content type category with a relation of sections and section has a relation of articles. The articles were not showing in the response as it's relational depth is more than 2

category
  - sections
    - articles

In my category controller:

  async find (ctx) {
    let categories = await strapi.query("category").find(ctx.query);

    categories = await Promise.all(categories.map(async (category) => {
      const sections = await strapi.query("section").find({ category: category.id });
      category.sections = sections
      return category
    }))

    return categories.map(category => sanitizeEntity(category, { model: strapi.models.category }))
  }

Hope this helps somebody :)

@leasytime
Copy link

async find (ctx) {
let categories = await strapi.query("category").find(ctx.query);

categories = await Promise.all(categories.map(async (category) => {
  const sections = await strapi.query("section").find({ category: category.id });
  category.sections = sections
  return category
}))

return categories.map(category => sanitizeEntity(category, { model: strapi.models.category }))

}

Hi Jimsheen,

Which versions of Strapi / Gatsby are you using? Can you maybe share your whole Category Controller?

Thanks in advance :)

@jimsheen
Copy link

jimsheen commented Feb 3, 2022

@leasytime

Hey, this is for Strapi v3.6.8 and Gatsby v3.11.1

Not much else in the controller other than the following:

const { sanitizeEntity } = require('strapi-utils');

module.exports = {
  async find (ctx) {
    let categories = await strapi.query("category").find(ctx.query);
    categories = await Promise.all(categories.map(async (category) => {
      let sections = await strapi.query("section").find({ category: category.id });
      sections = await Promise.all(sections.map(async (section) => {
        const articles = await strapi.query("article").find({ section: section.id });
        section.articles = articles;
        return section;
      }));
      category.sections = sections
      return category
    }))

    return categories.map(category => sanitizeEntity(category, { model: strapi.models.category }))
  }
};

@leasytime
Copy link

Hi James,

Thanks for swift reply.

Gotcha, makes sense. V4 works differently. You can address the nested fields it in your gatsby-config. Makes live easier. :)

@jimsheen
Copy link

jimsheen commented Feb 3, 2022

@leasytime No worries!

I do have a project running v4 but haven't run into nested relation issue like this yet as it's a flat structure.

I thought this was a Strapi problem not returning nested data - not Gatsby. Do you have an example of the gatsby-config you mentioned?

@leasytime
Copy link

leasytime commented Feb 3, 2022

Yes, please see below for a relational depth of 3 :

Page > Popular_Products > Image

collectionTypes: [{ name: 'page', endpoint: 'api/pages', api: { qs: { populate: [ 'blocks', 'faqs', 'popular_products.image' ] } }]

edit:
https://www.gatsbyjs.com/plugins/gatsby-source-strapi/
https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest/populating-fields.html#relation-media-fields

@soupette soupette mentioned this issue Feb 11, 2022
11 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants