Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autovalue not working when updating in nested object - simple example included #277

Closed
naschpitz opened this issue Jun 13, 2018 · 7 comments
Labels

Comments

@naschpitz
Copy link

naschpitz commented Jun 13, 2018

Hello there,

After updating SimpleSchema and Collection2 to the newest version (3.0.0), autovalue in nested objects started to behave differently. At first the "defaultValue: {}" was missing (https://github.com/aldeed/simple-schema-js/blob/master/CHANGELOG.md#100) and it solved the issue that autoValue was not being called at all, no matter upon insert or update.

Now I realized that upon updates, despite the fact autoValue is being called, the value returned is not persisted.

Test scenario:

const TestSchema = new TestSchema({
   test: {
       type: Date,
       label: "Updated At",
       optional: true,
       denyInsert: true,
       autoValue: function () {
           if (this.isUpdate || this.isUpsert)
           {
               console.log("test run");
               const date = new Date();
               console.log("value: " + date);
               return date;
           }
       }
   },
   dates: {
       type: DatesSchema,
       label: "Dates",
       optional: true,
       defaultValue: {}
   }
});
const DatesSchema = new SimpleSchema({
    createdAt: {
        type: Date,
        label: "Created At",
        optional: true,
        denyUpdate: true,
        autoValue: function () {
            if (this.isInsert) {
                console.log("createdAt run");
                const date = new Date();
                console.log("value: " + date);
                return date;
            }

            else if (this.isUpsert) {
                return {$setOnInsert: new Date()};
            }

            else
                this.unset();  // Prevent user from supplying their own value
        }
    },
    updatedAt: {
        type: Date,
        label: "Updated At",
        optional: true,
        denyInsert: true,
        autoValue: function () {
            if (this.isUpdate || this.isUpsert)
            {
                console.log("updatedAt run");
                const date = new Date();
                console.log("value: " + date);
                return date;
            }
        }
    },
});

Inserting:
If I insert a new document to the collection which TestSchema is attached to, log will print:

I20180613-13:35:27.027(-3)? createdAt run
I20180613-13:35:27.028(-3)? value: Wed Jun 13 2018 13:35:27 GMT-0300 (-03)

Taking a look at the collection, 'dates.createdAt' IS present as expected.

Updating
If I update a document to the collection which TestSchema is attached to, log will print:

I20180613-13:37:38.710(-3)? test run
I20180613-13:37:38.710(-3)? value: Wed Jun 13 2018 13:37:38 GMT-0300 (-03)
I20180613-13:37:38.711(-3)? updatedAt run
I20180613-13:37:38.711(-3)? value: Wed Jun 13 2018 13:37:38 GMT-0300 (-03)

Taking a look at the collection, 'test' IS present as expected, but 'dates.updatedAt' IS NOT PRESENT.

What am I missing here? Is this the expected behavior? I mean, both "test" and "updatedAt" are the same, the only difference is that one is nested and the other is not.

Being completely honest, I'm not certain if this is a collection2 issue or a simpleschema issue. Autovalue seems to be running as expected in both scenarios, insert and update, but the value is not persisted when on nested objects.

Thanks in advance!

@naschpitz
Copy link
Author

naschpitz commented Jun 13, 2018

Downgrading to aldeed:collection2@2.10.0 solved the issue, collections now have the expected fields upon insert and update.

@naschpitz naschpitz changed the title Autovalue not working when updating in nested object Autovalue not working when updating in nested object - simple example included May 20, 2019
@naschpitz
Copy link
Author

Just tested with aldeed:collection2@3.0.6 and simpl-schema@1.7.3 and it seems this issue is still there. Is this really an issue or am I doing something wrong?

@aldeed
Copy link
Collaborator

aldeed commented Jun 24, 2020

@naschpitz It would be helpful to see an example update call where this isn't working. Need to know what the modifier looks like, which operators it uses, which fields it is updating, etc.

@naschpitz
Copy link
Author

@aldeed, omg, you mentioned me and I didn't see, I'm so sorry.

There is another thread (#302) that seems like another dev has the same issue as I do.

In this comment I give a fairly simple example that if you try to update() the collection that implements 'Parent' schema the 'dates' object won't get a new 'updatedAt' value, in other words, autoValue function won't run when nested inside a object (in this case, 'dates'). Doesn't matter what 'otherStuff' is, could be as simples as a mere string field.

For testing you could just create a collection that implements the Parent schema (which in it's turn uses DatesSchema). When inserting a brand new object into that collection you will get 'createdAt' and 'updatedAt' correctly filled (thus indicating autoValue runs as expected), though 'updatedAt' won't get a new value (by running autoValue) if you try to update this object afterwards.

The following code should do the trick:

const ParentCollection = new Mongo.Collection('parentCollection');

const DatesSchema = new SimpleSchema({
  createdAt: {
      type: Date,
      label: "Created At",
      optional: true,
      autoValue: function () {
          if (this.isInsert)
              return new Date();
          
          else if (this.isUpsert)
              return {$setOnInsert: new Date()};

          else
              this.unset();  // Prevent user from supplying their own value
      }
  },
  updatedAt: {
      type: Date,
      label: "Updated At",
      optional: true,
      autoValue: function () {
          return new Date();
      }
  },
});

ParentCollection.schema = new SimpleSchema({
  otherStuff: {
     type: String,
     optional: true
  }
  dates: {
      type: DatesSchema,
      label: "Dates",
      optional: true,
      defaultValue: {}
  }
});

ParentCollection.attachSchema(ParentCollection.schema);

//===============================================================//

const id = ParentCollection.insert({otherStuff: 'someString'});

// After running insert() 'updatedAt' and 'createdAt' are correctly populated.
// Wait some seconds go by to be easier to notice the difference that should be seen in 'updatedAt', then run the code bellow.

ParentCollection.update(
   {_id: id}, 
   {$set: 
       {otherStuff: 'someOtherString'}
   }
);

// After running update(), 'updatedAt' isn't affected, there should be another (and more recent) Date returned by autoValue.
// 'updatedAt' is correctly altered in aldeed:collection2@2.10.0 and aldeed:simple-schema@1.5.4 during update(), but not in the newer versions.

@r-mach
Copy link

r-mach commented May 7, 2021

Hello,

We faced this issue and #302 building our product.
We didn't found a workaround yet.

Nested update in objects seems broken...

@mcorbelli
Copy link

By setting the parent object with a default value, the properties are correctly set

const TimestampSchema = new SimpleSchema({
    "dates": {
        type: Object,
        optional: true,
        defaultValue: {},
    },
    "dates.created_at": {
        type: Date,
        autoValue: function () {
            if (this.isInsert) {
                return dayjs().toDate();
            } else if (this.isUpsert) {
                return {
                    $setOnInsert: dayjs().toDate(),
                };
            } else {
                this.unset();
            }
        },
        optional: true,
    },
    "dates.updated_at": {
        type: Date,
        autoValue: function () {
            if (this.isUpdate) {
                return dayjs().toDate();
            } else {
                this.unset();
            }
        },
        optional: true,
    },
});

@aldeed aldeed closed this as completed in 2acf9b1 Feb 25, 2024
Copy link

🎉 This issue has been resolved in version 3.4.5 🎉

The release is available on:

If this makes you happy, please consider becoming a sponsor.

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants