How can we add dynamically new field on hook load

Context

I’m trying to add new fields dynamically on load hook based on tenants field value.

actions: [
    {
      name: 'Affect Url',
      type: 'single',
      fields: [
        {
          field: "tenants",
          type: ["Enum"],
          hook: 'onTenantsChange'
        }
      ],
      hooks: {
        load: async ({ fields, request }) => {
          const id = request.body.data.attributes.ids[0];
          const tenants = fields.find(field => field.field === 'tenants' );
          tenants.enums = await tenant.findAll({ raw: true }).map(tenant => tenant.id );
          tenants.value = await serviceLineTenant.findAll({
            where: { serviceLineIdKey: id },
            raw : true
          }).map(item => item.tenant_id);

          if(tenants.value.length) {
            tenants.value.forEach( async (element) => {
              const serviceLineTenantGet = await serviceLineTenant.findOne({ where : { serviceLineIdKey: id, tenantIdKey: element }});
              fields.push({
                field: 'Url for '+element,
                type: 'String',
                value: serviceLineTenantGet.url
              });
            });
          }

          return fields; 
        }, ...

For some reason the fields array is not updated even if the condition is verified. Is there any way to make it happens ?

Hello @Joel_Alexandre_Khang :wave:

When using an async function as Array.forEach callback, the subsequent code is executed without waiting for the callbacks. In your case, return fields is executed before fields.push.

Try a for of loop instead:

if (tenants.value.length) {
  for (const element of tenants.value) {
    const serviceLineTenantGet = await serviceLineTenant.findOne({ where : { serviceLineIdKey: id, tenantIdKey: element }});
    fields.push({
      field: 'Url for '+element,
      type: 'String',
      value: serviceLineTenantGet.url
    });
  }
}

return fields;

Let me know if this works :wink:

1 Like

Thank you @anon15528774, it works