Reputation: 1736
I am using Strapi CMS and struggling with fetching the nested/deep content’s data. E.g.: Let’s say, I have below content types created and relations are defined.
Person: Name, Age
Address: City, Country
Contact: Code, Number
Person has one Address
Address has many Contacts
Now the problem is, when I access ‘/persons’, I get only Name, Age and Address object. But address object does not have the contact information associated with the address.
Can somebody help me to get this resolved or point me towards any such article?
Upvotes: 9
Views: 16858
Reputation: 5697
This seem to work for me, Strapi v.4
Fetch components and dynamic zone components, using https://www.npmjs.com/package/qs
export async function getStaticProps({ params }) {
const query = qs.stringify(
{
populate: [
"pageHeading",
"seo",
"socialMedia",
"block.image",
"block.addressCard.image",
],
},
{
encodeValuesOnly: true,
}
);
const { data } = await fetcher(
`${process.env.NEXT_PUBLIC_STRAPI_API}/pages?publicationState=live&${query}&filters[slug]=${params.slug}`
);
return { props: { data } };
}
"pageHeading" - component
"block.addressCard.image" - addressCard nested component inside dynamic zone component
Upvotes: 0
Reputation: 1991
This one worked for me
let populate = ["parentCollection", "parentCollection.fieldToBePopulated"]
return await strapi.services.grandParentCollection.find({ condition }, populate)
Upvotes: 0
Reputation: 648
Only this worked for me
const data = await strapi
.query("grand_collection")
.model.find({ user: id })
.populate({ path: "parent_collection", populate: { path: "child_collection" } });
Upvotes: 1
Reputation: 369
None of the above answers worked for me unfortunately. I have a deeply nested relation that wasn't even show in the response(some people do get ID but I got nothing in the response).
Only thing that helped me was to build controller based off the suggestion in this issue here
Upvotes: 0
Reputation: 39
I was able to get some nested data using the following:
api/booking/controllers/booking.js:
async find(ctx) {
const entities = await strapi.services.booking.find(ctx.query, [
'class',
'class.capacity',
'class.date',
'class.category',
'class.category.name',
'class.type',
'class.type.name',
'class.startTime',
'class.endTime',
]);
}
return entities.map((entity) =>
sanitizeEntity(entity, { model: strapi.models.booking }),
);
},
where my booking
has a relation to class
and user
. So, by default it just comes back with the class id
's - but I'd like to be able to see fields from the class
relation all in the same payload.
ie, instead of this:
user: "123eqwey12ybdsb233",
class: "743egwem67ybdsb311"
I'm trying to get:
user: {
id: "123eqwey12ybdsb233",
email: "[email protected]",
...
},
class: {
id: "743egwem67ybdsb311",
capacity: 10,
type: {
name: "Individual",
description: "..."
...
}
...
}
Now, the above works for non-relational fields.. but for fields that are a relation of a relation (ie. class.category
and class.type
), it doesn't seem to work as I would've expected.
In my database, the relation chain is like so: booking
-> class
-> category
/ type
, where category
and type
each have a name
and some other fields.
Upvotes: 4
Reputation: 231
Firstly you'll need a custom controller function for this.
In /api/person/controllers/Person.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('person').find(ctx.query, ['address', 'contact']);
},
};
Another solution works for me as well:
module.exports = {
find: ctx => {
return strapi.query('person').find(ctx.query, [
{ path: 'address' },
{ path: 'contact' },
]);
},
};
Edited example with one level deeper populate:
module.exports = {
find: ctx => {
return strapi.query('person').find(ctx.query, [
{
path: 'address',
populate: {
path: 'contacts',
},
},
]);
},
};
For reference see the most recent beta docs:
https://strapi.io/documentation/3.0.0-beta.x/concepts/queries.html#api-reference
Upvotes: 18