Wait, the answer above is WRONG! I added a “location” component as well and then discovered that the wildcard * wasn’t working in conjunction with the specific business_information.logo
populate parameter. business_information
was populating in full, including media, and the top-level information not in components was also coming through, but no location
. So, basically, it seems you can’t actually chain the wildcard with more specific populate requests.
So after digging through docs a bit more I settled on simply chaining specific populate parameters. So, instead of wildcard + specific, I’m now just specifically calling components and the data I need inside them.
That brought me to this:
http://localhost:1337/api/venues?populate=business_information.logo&populate=location
However, location
has relations with a city
and a neighborhood
collection, and that’s not populating with just this call.
So now, what’s working for me is this–there might be a better way, but this is the first thing that worked for me:
http://localhost:1337/api/venues?populate[location][populate]=city&populate[location][populate]=neighborhood&populate[business_information][populate]=logo
This is getting a bit out of hand in terms of query params, though, so I decided to make a custom controller for returning the fields I want with just a call to populate=*.
This thread has helpful information on custom controllers for full population.
These docs are also helpful.
Ultimately, I landed on this:
"use strict";
/**
* venue controller
*/
const { createCoreController } = require("@strapi/strapi").factories;
// module.exports = createCoreController('api::venue.venue');
const uid = "api::venue.venue";
module.exports = createCoreController(uid, () => {
const components = {
location: {
populate: {
city: true,
neighborhood: true,
},
},
business_information: {
populate: {
logo: true,
},
},
};
return {
async find(ctx) {
// overwrite default populate=* functionality
if (ctx.query.populate === "*") {
const entity = await strapi.entityService.findMany(uid, {
...ctx.query,
populate: components,
});
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
return this.transformResponse(sanitizedEntity);
}
// maintain default functionality for all other request
return super.find(ctx);
},
async findOne(ctx) {
const { id } = ctx.request.params;
if (ctx.query.populate === "*") {
const entity = await strapi.entityService.findOne(uid, id, {
...ctx.query,
populate: components,
});
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
return this.transformResponse(sanitizedEntity);
}
return super.findOne(ctx);
},
};
});
After reading through some GitHub issues, there are apparently some additional wildcard selectors in the works that will populate all components/relations by default to certain depths, but this is working in the meantime!
Hopefully I don’t need another correction on this