Fetching contributors…
Cannot retrieve contributors at this time
executable file 335 lines (247 sloc) 10.8 KB



v2.0.0 (currently in alpha)



All callbacks have been changed to promises (except events).

To migrate your code, replace callback functions with promise handlers.


instance.load(123, (err, props) => {
  console.log(err, props);


try {
  const props = await modelInstance.load(123);
} catch (err) {
Default IDs

Previously, default ids were a custom random implementation, that wasn't very safe. Now uuid v1 is used by default.

Existing default ids should still work with the new versions, but any new default ids created after the update will be uuid v1.

Validation definitions

The format for validations was previously based on arrays, and strict indices had to be maintained for different parts of the definition.

Now validation definitions are objects and have proper keys.


someProperty: {
  type: 'integer',
  defaultValue: 5,
  validations: [
        min: 2,
        max: 20


someProperty: {
  type: 'integer',
  defaultValue: 5,
  validations: [
      name: 'minMax',
      options: {
        min: 2,
        max: 20

Previously there were cases where an error without a callback would just log out something about it and then continue on.

Now with Promises the behaviour will be similar (built-in unhandled rejection log) until Node.js starts to treat unhandled rejection by terminating the process.


Validation failures during save() previously returned a string 'invalid' and the errors then had to be checked in instance.errors.

Now validation failures during save() reject with a ValidationError.

Old: => {
  if (err) {
    if (err === 'invalid') {
      console.log('validation failed. reasons:', instance.errors);
    } else {
      console.error('saving failed with unknown error:', err);
  } else {


try {
} catch (err) {
  if (err instanceof nohm.ValidationError) {
    console.log('validation failed. reasons:', err.errors); // or instance.errors still, if you prefer
  } else {
    console.error('saving failed with unknown error:', err);
Linking errors

Previously linking errors had 2 different ways to be handled, controlled via the continue_on_link_error option.

This meant that either all linked objects were attempted to be stored, regardless of a failure in any linked object saving and success callback was called or as soon as one failed, no more links were stored during that save call and an immediate error callback would be issued.

The new behaviour is that it always attempts to save all linked objects in series (not parllel), but if any of them fail a rejection is issued at the end of the saving process. The reason it is done in series is that it makes saves more predictable (and thus testable) and it reduces the risk of race-conditions in the link chain.

This makes it abundandly clear that you are in an error state while at the same time allowing for recovery by inspecting the failures and acting accordingly.

A LinkError object is an extension of Error and additionally contains an "errors" array:

linkError.errors == [
    parent: NohmModel, // the instance on which .link() was performed
    child: NohmModel, // the instance that was given to .link() as argument
    error: Error | ValidationError | LinkError, // the error that occured while saving child.

In addition the callbacks that can be provided to the .link() call options object receive different arguments now. The errors array from the linked object is not passed seperately as the second argument anymore, instead it is just the thrown Error object as first argument and the linked object instance as second.

Old:, {
  error: (err, errors, linkedInstance) => {
    errors === linkedInstance.errors,
    other === linkedInstance

New:, {
  error: (err, linkedInstance) => {
    other === linkedInstance
  • model.load() and instance.load() now return the same as .allProperties(), meaning the id field is now included in addition to the normal properties
  • instance.valid() was renamed to instance.validate().
  • instance.allProperties() no longer has a json option (it stringified the return)
  • instance.propertyReset() no longer returns anything (previously always true)
  • nohm.factory() was previously only async if an id was provided - now it always returns a Promise, regardless of arguments provided
  • instance.remove() now sets property to null instead of 0. (this previously potentially caused issues with integer ids starting at 0)
  • The constructor for a model instance can no longer be used to immediately load the model by passing an id+callback. Use nohm.factory() instead or constructor and instance.load() afterwards.
  • passing invalid search keys (aka. property names that aren't defined as indexed) to .find() now throws an error instead of logging an error and returning an empty array.
  • nohm.connect() is renamed to nohm.middleware()
  • nohm.middleware() assumes that you are targeting browsers that have Promise support or that you have a Promise shim.
  • .findAndLoad() now returns an empty array if no instances are found instead of producing an error. This makes the behaviour the same in find() and findAndLoad().
  • is now a getter/setter that always returns null (no id set) or a string
  • the new instance.isLoaded is true when the instance has been loaded or saved at least once and has not been manually changed.
  • the new instance.isDirty is true when anything was done on the model that would require a .save() to persist it (changing .id, properties, pending relationchanges)
  • custom ID generators must resolve with strings that do not contain double colons (:)
  • behaviours (type functions) now always get strings as arguments, even if defaultValue or initialization would cast it differently
  • the regexp validator now only takes valid RegExp objects as the .regex option and resolves with an error

Non-breaking changes

  • instance.p() and instance.prop() have been deprecated. is the only version going forward.
  • updated dependencies

Almost the entire code base was rewritten in Typescript.

This means typing your models is now a lot easier. For additional examples of the typing possibilities, see the examples or the Typescript tests.


v0.9.8 - 06.02.2016

  • Add instance context to custom validators. (thanks johngeorgewright)

    exports.instanceValidation = function (value, opt, callback) {
        if ( < 50) {
        } else {
  • Update dependencies (thanks brysgo)

    • redis 2.4.2
    • (dev) nodeunit 0.9.1

v0.9.7 - 09.05.2015

  • BREAKS BACKWARDS COMPATIBILITY! (but only slightly and shouldn't really be an issue for most uses)
  • Fix for date parsing - only affects ISO date strings of format that has ' +HH:MM' or ' -HH:MM' at the end) and only on machines that are not set UTC (which servers usually are)
  • Update async & nodeunit dependencies

v0.9.6 - 05.09.2014

  • Add save option skip_validation_and_unique_indexes (thanks RoxasShadow)
  • Bug fixes (thanks exortech)
  • Update dependencies

v0.9.3 - 06.07.2013

  • Add endpoints option to find() (thanks to interruptz)
  • Add min>max options to find() that trigger descending search (thanks to interruptz)
  • Add return of the instance on shortform functions
  • Remove checking and setting meta.version on every model init
  • Bug fixes

v0.9.2 - 04.12.2012

  • Add findAndLoad as a convenience method
  • Fix a problem with getAll if different idGenerators were used

v0.9.1 - 21.08.2012

  • Fix uniques to now be completely case-insensitive

v0.9.0 - 06.06.2012

  • setClient/getClient now issue warnings on unconnected clients
  • Bug fixes

v0.9.0-pre3 - 04.03.2012

  • Support for common variants on bool/string/integer/timestamp
  • Bug fixes

v0.9.0-pre - 2012-03-14

  • BREAKS BACKWARDS COMPATIBILITY! change relation names for clearer handling ("child" is now "default", "xyzParent" is now "xyzForeign")
  • Added error handler to link/unlink
  • Bug fixes

v0.7.2 - 2012-01-19

  • add .sort()


  • Fix unique handling bugs


  • BREAKS BACKWARDS COMPATIBILTY! change validate() to be async only (validations all need to be async now), also changed validation usage syntax (see docs)
  • add nohm.connect() connect middleware that delivers browser validation js
  • Fix empty strings being locked on unique properties
  • Fix uniques to be case insensitive


  • unique values are now case insensitive when validating or searching
  • now compatible with node v0.6.3
  • now uses nodeunit v0.6.4


  • add Nohm.factory(modelName, [id, callback])
  • update redis dependency to 0.7.1

v0.6.1 & v0.6.2

  • bug fixes


  • changed id generation to unique strings by default (BREAKS BACKWARDS COMPATIBILTY)
  • added ability to choose from different id generation mechanisms (for example incremental or custom functions)
  • added short forms of functions where you don't need to create a new instance first to save/load/find/remove
  • changed this in callbacks to be the instance you manipulated/loaded
  • bug fixes


  • "value" in model properties renamed to "defaultValue"
  • "has()" renamed to "belongsTo()"
  • bug fixes


  • documentation
  • added instance.exists(id, callback)
  • added Nohm.setPrefix(prefix) to set the global redis prefix (default "nohm")
  • added Nohm.setClient(client) & Nohm.getClient() to set/get the global redis client (no default!)
  • removed instance.partialSave()
  • removed admin app (now in
  • bug fixes and code improvements


  • refactored a lot of the code


  • merged admin branch (this adds an optional and very basic admin web interface)
  • a lot of fixes for find and indexes


  • three small changes


  • added numLinks()
  • lots of bugfixes and some semi-internal changes


  • a few bugfixes in uniques, find() and load()


  • expose redis via nohm.redis


  • all basic functionality included