Ali Raza Sherazi
Ali Raza Sherazi

Reputation: 53

Strapi v4 relations population

Hi I’m migration from strapi v3 to v4. I’m stuck for quite sometime regarding population of relations in v4.

BEHAVIOUR IN V3

Previously in v3 if I queried a service, it populated uptill the 2nd level by default if I’m not wrong, and in the second level if returned foreign keys from the further nested tables/relations respectively.

Example case I have following relations: activity → cities → province , [images]

Querying activity like this in code:

const activity = await strapi.services.activity.findOne({ id });

would return activity → cities → { provinceforeignkey , images }

e.g. sample response

{
id: activity_id,
cities: [
id,
province: id_of_province,
images: [
// IMAGES DETAILED RESPONSE
]
]
}

BEHAVIOUR IN V4

I’m not able to get the desired response as above either by direct querying:

const activity = await strapi
        .service("api::activity.activity")
        .findOne(id,populate: ["cities"]);

Or by using entityService:

await strapi.entityService.findOne(
        "api::activity.activity",
        id,
       populate: ["cities"]
      );

I know we can use populate field to populate the desired relation, but on second level e.g. province case inside cities I need the id of province not the entire object population.

This is really important to us as we’ve tonnes of custom apis and custom code already implemented in v3 as per the following approach, otherwise we would have to go and change each case specifically in frontend and backend.

Can anyone guide me on this?

Upvotes: 0

Views: 960

Answers (1)

antokhio
antokhio

Reputation: 2004

the entityService and db.query accept fields parameter that is undocumented but may work? However, what i would recommend is doing your own normalize function like:

let activities = await strapi.db.query('api::activity.activity')
    .findOne({where: { id }, populate: { cities: { populate: ['state'] } } );

return normalizeManyActivities(activities)

and

const normalizeActivity = (activity) => 
   ({...activity, 
     cities: activity.cities.map(city => 
       ({...city, state: city.state.id })
    })
);

const normalizeManyActivities = (activities) => 
    activities.map(activity => normalizeActivity(activity));

and the second approach is to use middleware's witch you can take reference from here: https://www.youtube.com/watch?v=YIbhKm1o0fE

Upvotes: 1

Related Questions