Edit nested object with smart fields

Hello community!

I am trying to implement smart fields to edit fields stored in a object (as ForestAdmin only supports first level edit in the UI).

Here’s an abstract of my schema:

const criteriaSchema = mongoose.Schema({
  type: [{
    type: String,
    enum: ['A1', 'A2', 'A3']
  }],
  jobType: [{
    type: String,
    enum: ['B1', 'B2', 'B3', 'B4']
  }],
  ...
})

const schema = mongoose.Schema({
  ...,
  criteria: criteriaSchema,
  ...,
  })```

And here’s my forest config:

  actions: [...],
  fields: [{
    field: 'Criteria Type',
    type: ['Enum'],
    enums: ['A1', 'A2', 'A3'],
    get: property => {
      if (property && property.criteria && property.criteria.type) return property.criteria.type
      else return null
    },
    set: ((property, value) => {
      if (!property.criteria) {
        property.criteria = {};
      }
      property.criteria.type = value;
    })
  }, {
    field: 'Criteria JobType',
    type: ['Enum'],
    enums: ['B1', 'B2', 'B3', 'B4'],
    get: property => {
      if (property && property.criteria && property.criteria.jobType) return property.criteria.jobType
      else return null
    },
    set: ((property, value) => {
      if (!property.criteria) {
        property.criteria = {};
      }
      property.criteria.jobType = value;
    })
  }],
  segments: [],
})

Expected behavior

When I edit a particular Smart Field, others Smart Fields should not change (it should only edit the field I’m a actually editing)

Actual behavior

  • if I edit “Criteria Type”, “Criteria JobType” becomes empty
  • if I edit “Criteria JobType”, “CriteriaType” becomes empty
  • if I edit both, it works fine

Note that it only affects smart fields.
Am I missing something in the setter declaration?

Thanks in advance for your help! :slight_smile:

Context

  • forest-express-mongoose: 6.7.2
  • express: ~4.17.1
  • mongoose: ~5.8.2

Hi @barthelemy,

Sorry to read that you have an issue here.
Let me create a ticket to let the tech team dig into this.

1 Like

Adding some extra info: I have noticed the same issue with other Smart Field types

Not sure to understand your last comment.
Do you think this issue is restricted to some kind of Smart Fields types?

When I wrote my first comment, the only test I ran was on ‘Enum’ types, but I also noticed this behavior with other types.

Ok thanks. Indeed I think the field type is not a criteria to reproduce the issue.

You can follow the status for this ticket here:

Hello @barthelemy,

I have been able to reproduce your issue and can suggest you a quickfix :slight_smile:
The first parameter of the set method won’t be the record but an object with the modified data.
That’s why the behaviour appears, property.criteria is empty by default, if only the smart field has been updated.

You can directly get the record yourself and fix this issue (here I use the students collection for demonstration purposes, replace it with your own collection):

const { collection, ResourceGetter } = require('forest-express-mongoose');
const { students } = require('../models');

collection('students', {
  actions: [],
  fields: [{
    field: 'Criteria Type',
    type: ['Enum'],
    enums: ['A1', 'A2', 'A3'],
    get: property => {
      if (property && property.criteria && property.criteria.type) return property.criteria.type
      else return null
    },
    set: ((property, value) => {
      return new ResourceGetter(students, {recordId: property._id}).perform().then(record => {
        property.criteria = record.criteria;
        property.criteria.type = value;
      });
    })
  }, {
    field: 'Criteria JobType',
    type: ['Enum'],
    enums: ['B1', 'B2', 'B3', 'B4'],
    get: property => {
      if (property && property.criteria && property.criteria.jobType) return property.criteria.jobType
      else return null
    },
    set: ((property, value) => {
      return new ResourceGetter(students, {recordId: property._id}).perform().then(record => {
        property.criteria = record.criteria;
        property.criteria.jobType = value;
      });
    })
  }],
  segments: [],
});

It will now work properly :slight_smile:

Tell me if it helps :wink:

Many thanks Guillaume it works perfectly! Have a nice day :blush:

1 Like