mobx-react-form icon indicating copy to clipboard operation
mobx-react-form copied to clipboard

Newly added field in nested array not defined when using form.update()

Open mattscooter opened this issue 6 years ago • 1 comments

I have an issuse that I can't seem to figure out. It has to do with populating a nested array when I add a new field to the form definition.

I'm not sure the best way to expain it so I might just walk through an example:

I start out with defining a nested field using separated definitions.

  fields = [
    'title',
    'contact',
    'lineItems[]',
    'lineItems[].service',
    'lineItems[].quantity',
    'lineItems[].sellPrice',
    'lineItems[].notes',
    'lineItems[].duration'
  ];

Using this schema I have stored the data entered into my database.

After a while I have realised that I need to include the taxRate in my line items so I add it to my field definition like this:

  fields = [
    'title',
    'contact',
    'lineItems[]',
    'lineItems[].service',
    'lineItems[].quantity',
    'lineItems[].sellPrice',
    'lineItems[].notes',
    'lineItems[].duration',
    'lineItems[].taxRate',
  ];

Now when I retreive the existing data from the database and use form.update() the newly added taxRate field is not defined. Which causes my app to crash with an error:

utils.js:201 Uncaught Error: The selected field is not defined (taxRate)

Let's recreate the database update call inside my app:

form.update({
  title: 'Test',
  contact: '5a0ac7597424355c5f31ce2c',
  lineItems: [ {service: '59f018c604ad9b45750f0b7d', quantity: 1, sellPrice: 100, notes: '', duration: 90 } ]
}) 

This is what the fields are defined (copied from my apps console output on chrome):

form.$('lineItems').$(0).fields._data = 
	duration : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(3), observersIndexes: {…}, diffValue: 0, …}
	notes : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
	quantity : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
	sellPrice : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
	service : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}	

You can see that the taxRate field is not defined. Should it be? I understand if I was using init() then I am overwriting the form definition but an update should still have my defined fields set, shouldn't it?

Now if instead I just add a new empty row the new field taxRate is there:

form.$('lineItems').add()

form.$('lineItems').$(1).fields._data = 
    duration : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(3), observersIndexes: {…}, diffValue: 0, …}
    notes : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
    quantity : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
    sellPrice : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
    service : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(4), observersIndexes: {…}, diffValue: 0, …}
    taxRate : ObservableValue {name: "[email protected]", isPendingUnobservation: true, observers: Array(3), observersIndexes: {…}, diffValue: 0, …}

I know that if I add an empty field taxRate into my database then I can get it to work, however I don't want to have to modify the database everytime I add a field to a nested array in my form.

Is this a bug or is this expected? If its expected behavior how should I be handling adding new fields to a nested array in my form?

mattscooter avatar Apr 19 '18 06:04 mattscooter

if you are using the init() method could be bugged. It will deprecated in the next version.

foxhound87 avatar Aug 11 '22 14:08 foxhound87

Need more info on your code to replicate the issue. The init() method has been deprecated in the next version.

foxhound87 avatar Feb 27 '23 14:02 foxhound87