No image in the API response

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 :smiley: