Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleSchema invalid keys with nested autoValue

Tags:

schema

meteor

I have a schema like so (fluff cut out):

Schemas.people = new SimpleSchema({
  note: {
    type: [Schemas.notes],
    optional: true,
    defaultValue: []
  },
  updates: {
    type: [Schemas.updates],
    optional:true,
    autoValue:function(){
      if (this.isInsert) {
        return [{
          at: new Date,
          user_id: this.userId
        }];
      } 
      return {
        $push:{
          at: new Date,
          user_id: this.userId
        }
      }
    }
  }
});

And the notes schema looks like:

Schemas.notes = new SimpleSchema({
  note: {
    type: String,
    autoform: {
      afFieldInput:{
        type:"textarea"
      }
    },
    optional: true
  },
  updates: {
    type: [Schemas.updates],
    optional:true,
    autoform:{
      omit:true
    },
    autoValue:function(){
      if (this.isInsert) {
        return [{
          at: new Date,
          user_id: this.userId
        }];
      } 
      return {
        $push:{
          at: new Date,
          user_id: this.userId
        }
      }
    }
  }
});

And the updates schema is super simple:

Schemas.updates = new SimpleSchema({
  at: {
    type: Date
  },
  user_id:{
    type: Meteor.ObjectID
  }
});

The "updates" field on the people schema saves the date/user id as expected when an update is made. However, it fails on the notes schema:

SimpleSchema invalid keys for "blablabla" context:
0: Object
  name: "note.0.updates.0.at"
  type: "keyNotInSchema"
  value: Mon May 11 2015 11:57:58 GMT-0400 (Eastern Daylight Time)
1: Object
  name: "note.0.updates.0.user_id"
  type: "keyNotInSchema"
  value: "abcd1234"

I believe that the "name" should look like "people.note.0.updates.0.at" but I'm unsure that this assumption is correct and I'm completely unsure how to go about making that happen.

Update:

Code used to update people

  {{#autoForm collection="people" id=formId type="update" class="update" autocomplete="off" doc=getDocument autosave=true template="quickform"}}
  {{> afQuickField name='note' template="quickform" }}
  {{/autoForm}}

formId returns a randomish ID string and getDocument passes in the correct collection.

Schemas.notes._schemaKeys does not list the at and user_id fields... but Schemas.people._schemaKeys does.

People schema shows: [..., "updates.$.at", "updates.$.user_id", ...]

Notes schema shows: ["note", "updates", "updates.$"]

How bizarre.

like image 467
Randy Hall Avatar asked Oct 31 '22 04:10

Randy Hall


2 Answers

Note that Meteor uses standard JavaScript syntax and therefore has the same restrictions, for example as you already realized order of code is important.

Let's have a look.

Schemas.notes = new SimpleSchema({
  updates: {
    type: [Schemas.updates]
  }
}

There are no nested functions in this code, therefore every code of line will be executed, before Meteor continues with the next Schema definition. Schema.updates will be dereferenced immediately, although it isn't set yet. type will be an array containing null and that finally makes SimpleSchema assume that no fields are allowed at all.

like image 79
Christian Strempfer Avatar answered Jan 04 '23 15:01

Christian Strempfer


The issue is with the order in which the schemas are declared. Which I suppose makes sense? I was declaring "notes" before "updates", and "people" last. Putting "updates" first fixed the issue completely.

I'm going to report this as a possible bug to the collection repo.

like image 26
Randy Hall Avatar answered Jan 04 '23 13:01

Randy Hall