New agent smart action - getRecordId retruns error

Feature(s) impacted

Implementing an Action I would like to Get the id of selected record to fill it in a form field.
code:

{
                label: "offre_id",
                isReadOnly: true,
                isRequired: true,
                type: "Number",
                defaultValue: async context=>{
                    console.log('context = ', context);
                    const id = await context.getRecordId();
                    console.log('==== id', id);
                    return id
                }
            },

Observed behavior

when form is loading I got this error:

On the log I got

context =  ActionContextSingle {
  realDataSource: DataSourceDecorator {
    decorators: WeakMap { <items unknown> },
    childDataSource: ChartDataSourceDecorator {
      decorators: [WeakMap],
      childDataSource: [DataSourceDecorator],
      CollectionDecoratorCtor: [class ChartCollectionDecorator extends CollectionDecorator],
      charts: [Object]
    },
    CollectionDecoratorCtor: [class ActionCollectionDecorator extends CollectionDecorator]
  },
  _caller: {
    id: 74678,
    email: 'adel@clevermate.fr',
    firstName: 'adel',
    lastName: 'djidjik',
    team: 'Operations',
    role: 'Operations',
    permissionLevel: 'admin',
    renderingId: 293219,
    tags: {},
    iat: 1737971620,
    exp: 1737975220,
    timezone: 'Africa/Algiers',
    requestId: '68237ef7-54e9-44f2-aa43-e0680de38743',
    request: { ip: '::1' }
  },
  realCollection: ActionCollectionDecorator {
    childCollection: ChartCollectionDecorator {
      childCollection: [SortEmulate],
      dataSource: [ChartDataSourceDecorator],
      charts: {},
      markSchemaAsDirty: [Function (anonymous)],
      lastSchema: [Object]
    },
    dataSource: DataSourceDecorator {
      decorators: [WeakMap],
      childDataSource: [ChartDataSourceDecorator],
      CollectionDecoratorCtor: [class ActionCollectionDecorator extends CollectionDecorator]
    },
    actions: {
      'Ajouter candidature': [Object],
      'Affecter un programme': [Object],
      'Affecter un eleve': [Object],
      'Modifier un besoin': [Object]
    },
    markSchemaAsDirty: [Function (anonymous)],
    lastSchema: {
      actions: [Object],
      charts: [],
      countable: true,
      fields: [Object],
      searchable: true,
      segments: []
    }
  },
  formValues: {},
  filter: Filter {
    conditionTree: ConditionTreeBranch { aggregator: 'And', conditions: [Array] },
    search: null,
    searchExtended: false,
    segment: null,
    liveQuerySegment: null
  },
  _changedField: undefined,
  queries: [],
  projection: Projection(0) [],
  hasFieldChanged: [Function (anonymous)]
}
error: [500] POST /forest/_actions/c_besoins/0/ajouter-candidature/hooks/load - 1429ms

===== An exception was raised =====
POST /forest/_actions/c_besoins/0/ajouter-candidature/hooks/load?{
 timezone: Africa/Algiers
}

Body {
 data: {
  attributes: {
   ids: [
    1716
   ],
   collection_name: c_besoins,
   parent_collection_name: null,
   parent_collection_id: null,
   parent_association_name: null,
   all_records: false,
   all_records_subset_query: {
    fields[c_besoins]: id,nb_candidatures,nb_stand_by,SA,priorité,stade,type_enum,matieres,comment,level,Lieu,contactFullName,contactWpLink,
    page[number]: 1,
    page[size]: 15,
    filters: {\field\:\action_a_mener_enum\,\operator\:\equal\,\value\:\Trouver pépite\},
    sort: -id,
    timezone: Africa/Algiers
   },
   all_records_ids_excluded: [],
   smart_action_id: c_besoins-Ajouter@@@candidature,
   signed_approval_request: null
  },
  type: action-requests
 }
}

 Cannot read properties of undefined (reading '0') 

TypeError: Cannot read properties of undefined (reading '0')
    at ActionContextSingle.getRecordId (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/datasource-customizer/src/decorators/actions/context/single.ts:13:23)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async defaultValue (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/forest/c_besoins.ts:683:32)
    at async ActionCollectionDecorator.dropDefault (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/datasource-customizer/src/decorators/actions/collection.ts:259:28)
    at async Promise.all (index 5)
    at async ActionCollectionDecorator.getForm (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/datasource-customizer/src/decorators/actions/collection.ts:103:31)
    at async ActionRoute.handleHook (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/agent/src/routes/modification/action/action.ts:163:18)
    at async ErrorHandling.errorHandler (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/agent/src/routes/system/error-handling.ts:24:7)
    at async Logger.logger (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/agent/src/routes/system/logger.ts:20:7)
    at async bodyParser (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/koa-bodyparser/index.js:78:5)
===================================

Expected behavior

should Get the id of selected record and fill it in form field “offre_id”

  • Project name: Clevermate v2
  • Environment name: dev
  • Agent technology: (nodejs,
  • Agent (forest package) name & version: 1.55.1
  • Database type: postgres

Hello @Adel_de_Clevermate,

After a quick investigation on my side, this can only happen when the selected record no longer matches the filters applied on the frontend.

I would assume that the record on which you tried to execute the action no longer matches the condition on action_a_mener_enum.

Could you try to refresh the page and retry the action ?

If it is indeed the cause, I will update the error message to improve UX and understandability on this.

Best regards,

1 Like

Hi @dogan.ay

Thank you for your answer.

However I tried to refresh the page and retry but I still getting the same error.
The action_a_mener is not changed for the record selected.


For more context also:
Here I list the segment “Offres” which filters on records that have action=“Trouver pepite” only.
I noticed that I set segment for “All” the error is not showing, it shows only when the filter action=“Trouver pepite” is set for the collection! :thinking:

Hello @Adel_de_Clevermate,

Can you please share the content of context.filter.conditionTree in the action hook ? :pray:
there is probably a discrepancy of filters.

@Nicolas.M
Here is the log:

context.filter.conditionTree =  ConditionTreeBranch {
  aggregator: 'And',
  conditions: [
    ConditionTreeLeaf {
      field: 'action_a_mener_enum',
      operator: 'Equal',
      value: 'Trouver pépite'
    },
    ConditionTreeLeaf { field: 'id', operator: 'Equal', value: 1715 }
  ]
}
error: [500] POST /forest/_actions/c_besoins/0/ajouter-candidature/hooks/load - 285ms

===== An exception was raised =====
POST /forest/_actions/c_besoins/0/ajouter-candidature/hooks/load?{
 timezone: Africa/Algiers
}

Body {
 data: {
  attributes: {
   ids: [
    1715
   ],
   collection_name: c_besoins,
   parent_collection_name: null,
   parent_collection_id: null,
   parent_association_name: null,
   all_records: false,
   all_records_subset_query: {
    fields[c_besoins]: id,action_a_mener_enum,nb_candidatures,nb_stand_by,SA,priorité,stade,type_enum,matieres,comment,level,Lieu,contactFullName,contactWpLink,
    page[number]: 1,
    page[size]: 15,
    filters: {\field\:\action_a_mener_enum\,\operator\:\equal\,\value\:\Trouver pépite\},
    segmentName: Offres,
    sort: -id,
    timezone: Africa/Algiers
   },
   all_records_ids_excluded: [],
   smart_action_id: c_besoins-Ajouter@@@candidature,
   signed_approval_request: null
  },
  type: action-requests
 }
}

 Cannot read properties of undefined (reading '0') 

TypeError: Cannot read properties of undefined (reading '0')
    at ActionContextSingle.getRecordId (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/datasource-customizer/src/decorators/actions/context/single.ts:13:23)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async defaultValue (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/forest/c_besoins.ts:683:32)
    at async ActionCollectionDecorator.dropDefault (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/datasource-customizer/src/decorators/actions/collection.ts:259:28)
    at async Promise.all (index 5)
    at async ActionCollectionDecorator.getForm (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/datasource-customizer/src/decorators/actions/collection.ts:103:31)
    at async ActionRoute.handleHook (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/agent/src/routes/modification/action/action.ts:163:18)
    at async ErrorHandling.errorHandler (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/agent/src/routes/system/error-handling.ts:24:7)
    at async Logger.logger (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/@forestadmin/agent/src/routes/system/logger.ts:20:7)
    at async bodyParser (/home/adel/clevermate/clevermate-deploy/clevermate-forest-v2/node_modules/koa-bodyparser/index.js:78:5)
===================================

Does your database column action_a_mener_enum contains values like Trouver pépite in your database ? It looks more like a label and less like a value to me.
I’m thinking about this post: is action_a_mener_enum a smart field that you used to define the enum ? :pray:

could you let me know what is the network request URL that is sent when displaying ?

the segment “Offres” which filters on records that have action=“Trouver pepite” only

I would only need the GET query string properties, which contains the filter
You can hit the refresh button with your browser dev tools opened to the Network tab or similar

http://localhost:3310/forest/c_besoins?timezone=Africa%2FAlgiers&fields%5Bc_besoins%5D=id%2Caction_a_mener_enum%2Cnb_candidatures%2Cnb_stand_by%2CSA%2Cpriorit%C3%A9%2Cstade%2Ctype_enum%2Cmatieres%2Ccomment%2Clevel%2CLieu%2CcontactFullName%2CcontactWpLink&filters=%7B%22field%22%3A%22action_a_mener_enum%22%2C%22operator%22%3A%22equal%22%2C%22value%22%3A%22Trouver%20p%C3%A9pite%22%7D&page%5Bnumber%5D=1&page%5Bsize%5D=15&segmentName=Offres&sort=-id

Hello @Nicolas.M

It seems to working for me now, Indeed I think the issue was caused by the field action_a_mener_enum So what I did was:

collection.replaceFieldOperator(field+'_enum', "Equal", async (value, context) => {
      return {
        field: field, operator: "Equal", value
      }
    });

I overrided the Field Operator for the field to keep it filtering with the original field name without the “_enum”

The full code

export function setFieldEnums(collection, field, enumValues) {
  const OPERATORS = ['Present',
    'Blank',
    'Missing',
    'Equal',
    'NotEqual',
    'LessThan',
    'GreaterThan',
    'In',
    'NotIn',
    'Matches',
    'ILike',
    'Like',
    'StartsWith',
    'EndsWith',
    'Contains',
    'NotContains',
    'LongerThan',
    'ShorterThan',
    'Before',
    'After',
    'AfterXHoursAgo',
    'BeforeXHoursAgo',
    'Past',
    'Future',
    'PreviousMonthToDate',
    'PreviousMonth',
    'PreviousQuarterToDate',
    'PreviousQuarter',
    'PreviousWeekToDate',
    'PreviousWeek',
    'PreviousXDaysToDate',
    'PreviousXDays',
    'PreviousYearToDate',
    'PreviousYear',
    'Today',
    'Yesterday',
    'IncludesAll']
  collection.addField(field + '_enum', {
    columnType: 'Enum',
    enumValues: enumValues,
    dependencies: [field],
    getValues(records) {
      return records.map(record => record[field]);
    },
  })
    .removeField(field)
    .replaceFieldWriting(field + '_enum', async value => {
      return { [field]: value };
    });

  OPERATORS.forEach(operator => {
    collection.replaceFieldOperator(field + '_enum', operator, async (value, context) => {
      return {
        field, operator, value
      }
    });
  });
}
2 Likes

I’m glad that you found the root cause of the issue. Is the behaviour conform to your expectations now ? I’ll let you mark your post as solved if this is ok for you :pray:

In the meantime, I will create a ticket to throw a better error when the agent wont find the record through getRecordId

1 Like