System Information
- Strapi Version: 4.24.2
- Operating System: Windows 10
- Database: sqlite
- Node Version: 18.17.0
- NPM Version: 9.8.0
Recently, I added a repeatable component to one of my Content-types.
{
"kind": "collectionType",
"collectionName": "coordinators",
"info": {
"singularName": "coordinator",
"pluralName": "coordinators"
},
"attributes": {
...,
"saved_segments": {
"type": "component",
"repeatable": true,
"component": "organization.follower-filters"
}
}
}
I created a method for adding new items to this “saved_segments” attribute. First, I tried using the entityService for creating the new component and the updating the entity adding it to the list but ended up always in an “ApplicationError: Some of the provided components in saved_segments are not related to the entity”.
So then, I changed the approach to use db.query (which ended up working for me, but not in a suitable way). With strapi db query I am able to create the new component propertly and update the entity adding it to the attribut list, however, if I add another component to the list, the update duplicates every single item.
Taking into account that providing only the new item in the update would override the previous values, I could not find any other solution to this than clearing up the attribute value with an empty update and then doing a second update with the full correct list.
In order to ilustrate the explanation a little better, my create method finally looks like this:
async createSegment(ctx) {
const user = ctx.state.user;
const segmentData = ctx.request.body.data;
// Create the new segment with the provided data
const segment = await strapi.db.query('organization.follower-filters').create({
data: {
name: segmentData.name,
province: segmentData.province,
study_type: segmentData.study_type,
study_area: segmentData.student_area,
},
populate: ["study_area"]
});
// Find the actual saved_segments value for the specified coordinator
const coordinators = await strapi.entityService.findMany("api::coordinator.coordinator", {
populate: {
saved_segments: {
populate: ["study_area"]
}
},
filters: {
user: {
id: user.id
}
},
fields: ["id"]
}
);
const updatedSegments = [...coordinators[0].saved_segments, segment]; // How the new segments list should end
/**
* NOTE: in the current version, repeatable components update is not working propertly.
* - First of all, entityService.update is not working for repeatable components as it needs to somehow link the new created component to the entity before updating.
* - Secondly, while using db query update, the previous components are being duplicated while updating, that's why we need to empty the field before adding the new one.
*/
if(updatedSegments.length > 1)
await strapi.db.query('api::coordinator.coordinator').update({
where :{
id: coordinators[0].id
},
data : {
saved_segments: []
}
});
return strapi.db.query('api::coordinator.coordinator').update({
where :{
id: coordinators[0].id
},
data : {
saved_segments: updatedSegments
}
});
}
Eventhough i can keep working with this solution, I would like to find a way to avoid having to do 2 updates in a row in order to add a new item. I would appreciate if someone could help me with this or find a solution where you could do this using the entityService.