Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add virtual property of type Array using Keystone.js?

This is my code for my model: 'Info' and its the tokens property that creates the problem.

var keystone = require('keystone'),
    Types = keystone.Field.Types;
var Info = new keystone.List('Info');
Info.add({
    title: { type: String, required: true, initial: true },
    subtitle: { type: String, initial: true },
    content: { type: Types.Markdown, height: 500, initial: true },
    author: { type: Types.Relationship, ref: 'User', initial: true },
    date: { type: Types.Date, default: Date.now, initial: true },
    published: { type: Boolean, default: false, initial: true },
    tokens: { type: Array, virtual: true, noedit: true, collapse: true }
});

Info.defaultColumns = 'title, author, date|15%, published|15%'
Info.register();

When running the app i get:

Error: Unrecognised field constructor: function Array() { [native code] }
at List.field (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/node_modules/keystone/lib/list.js:315:10)
at List.<anonymous> (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/node_modules/keystone/lib/list.js:200:16)
at List.<anonymous> (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/node_modules/keystone/lib/list.js:191:5)
at List.<anonymous> (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/node_modules/keystone/lib/list.js:230:5)
at Function._.each._.forEach (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/node_modules/keystone/node_modules/underscore/underscore.js:82:22)
at List.add (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/node_modules/keystone/lib/list.js:204:4)
at Object.<anonymous> (/Users/bobmoff/Dropbox (Mobiento)/IMGNRY/Nordea/dev/code/rantebevis-cms/models/infos.js:4:6)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
like image 804
bobmoff Avatar asked Feb 27 '14 09:02

bobmoff


1 Answers

I'm not sure what you are planning to store / do with tokens, so if this doesn't answer your question please clarify :)

I'm guessing you either mean:

  • an array path that's stored in the database, or
  • a virtual property whose value is not stored but is calculated at runtime.

Both are possible by modifying the mongoose schema directly, rather than using Keystone's add method on the List.

To add an array path (so you could, for example, store an array of string tokens generated through some process on save) you would do this:

var keystone = require('keystone'),
    Types = keystone.Field.Types;

var Info = new keystone.List('Info');
Info.add({
    title: { type: String, required: true, initial: true },
    subtitle: { type: String, initial: true },
    content: { type: Types.Markdown, height: 500, initial: true },
    author: { type: Types.Relationship, ref: 'User', initial: true },
    date: { type: Types.Date, default: Date.now, initial: true },
    published: { type: Boolean, default: false, initial: true }
});

Info.schema.add({
    tokens: { type: [String] }
});

Info.defaultColumns = 'title, author, date|15%, published|15%';
Info.register();

To create a virtual property, you'd specify it with a getter like this:

Info.schema.virtual('tokens', function() {
    var tokens = [];
    // calculate tokens somehow
    return tokens;
});

By accessing the schema you bypass Keystone's list, which means the fields won't show up in the Admin UI. There's an issue to add support for custom templates in the Admin UI though which will allow this in the future.

There's also an issue for an array field type, so if you are storing strings in an array for now you'll be able to include it in the Admin UI when that feature is implemented.

On a related note, all the functionality mongoose offers is available via the schema so you can define things like custom methods, statics and pre / post save hooks too. For more about what you can do with mongoose schemas, check out the guide.

like image 193
Jed Watson Avatar answered Nov 05 '22 17:11

Jed Watson