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

Possibly unhandled TypeError: Cannot read property 'validate' when using model.post('retrieve') #315

Closed
justingosan opened this issue Aug 13, 2015 · 12 comments

Comments

@justingosan
Copy link

Hi!

Whenever I use:

model.post('retrieve', function(next) {
        next();
    });

...and try to query or create that model, I get this error

Possibly unhandled TypeError: Cannot read property 'validate' of undefined
    at /Users/Justin/Projects/Node/project_name/node_modules/thinky/lib/model.js:897:36
    at tryCatch1 (/Users/Justin/Projects/Node/project_name/node_modules/thinky/node_modules/bluebird/js/main/util.js:43:21)
    at Promise$_callHandler [as _callHandler] (/Users/Justin/Projects/Node/project_name/node_modules/thinky/node_modules/bluebird/js/main/promise.js:627:13)
    at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (/Users/Justin/Projects/Node/project_name/node_modules/thinky/node_modules/bluebird/js/main/promise.js:641:18)
    at Promise$_settlePromiseAt [as _settlePromiseAt] (/Users/Justin/Projects/Node/project_name/node_modules/thinky/node_modules/bluebird/js/main/promise.js:800:14)
    at Async$_consumeFunctionBuffer [as _consumeFunctionBuffer] (/Users/Justin/Projects/Node/project_name/node_modules/thinky/node_modules/bluebird/js/main/async.js:75:12)
    at Async$consumeFunctionBuffer (/Users/Justin/Projects/Node/project_name/node_modules/thinky/node_modules/bluebird/js/main/async.js:38:14)
    at process._tickDomainCallback (node.js:381:11)

Here's my model schema:

var model = thinky.createModel('User', {
        type: thinky.type.string().default('User'),
        id: thinky.type.string(),
        username: thinky.type.string(),
        password: thinky.type.string(),
        first_name: thinky.type.string(),
        last_name: thinky.type.string(),
        email: thinky.type.string(),
        role: thinky.type.string(),
        organization_id: thinky.type.string(),
        date_modified: thinky.type.date().default(thinky.r.now()),
        date_created: thinky.type.date().default(thinky.r.now()),
        isDeleted: thinky.type.boolean().default(false)
    }, {
        enforce_extra: 'remove'
    });

    model.belongsTo(thinky.models.Organization, 'organization', 'organization_id', 'id');

    model.pre('save', function(next){
        this.date_modified = thinky.r.now();
        next();
    });

    model.post('save', function(next) {
        delete this.password;
        next();
    });

    model.post('retrieve', function(next) {
        delete this.password;
        next();
    });

The Organization model simply contains a name (string) field.
Using [email protected]

Any thoughts?

@neumino
Copy link
Owner

neumino commented Aug 13, 2015

This works fine for me:

var thinky = require('./lib/thinky.js')();
var type = thinky.type;

var model = thinky.createModel('User', {
  type: thinky.type.string().default('User'),
  id: thinky.type.string(),
  username: thinky.type.string(),
  password: thinky.type.string(),
  first_name: thinky.type.string(),
  last_name: thinky.type.string(),
  email: thinky.type.string(),
  role: thinky.type.string(),
  organization_id: thinky.type.string(),
  date_modified: thinky.type.date().default(thinky.r.now()),
  date_created: thinky.type.date().default(thinky.r.now()),
  isDeleted: thinky.type.boolean().default(false)
}, {
  enforce_extra: 'remove'
});

var Organization = thinky.createModel('Organization', {
  id: type.string()
});

model.belongsTo(Organization, 'organization', 'organization_id', 'id');

model.pre('save', function(next){
  this.date_modified = thinky.r.now();
  next();
});

model.post('save', function(next) {
  delete this.password;
  next();
});

model.post('retrieve', function(next) {
  delete this.password;
  next();
});

var doc = new model({
  username: "foo",
  password: "1234"
});

doc.save().then(function() {
  return model.get(doc.id).run()
}).then(function(result) {
  console.log(result);
  process.exit(0);
}).error(function(error) {
  console.log(error);
  process.exit(1);
});

Can you provide a script that triggers this error?

@neumino
Copy link
Owner

neumino commented Aug 13, 2015

Using the query model.run() works fine too. I'm not sure how data[i] could be undefined. The only way would be that the retrieve hooks set data[i] to undefined but I don't see how that's possible.

@justingosan
Copy link
Author

Hmm this is weird. It doesn't throw an error if I comment out the retrieve hook. I'll dig in some more.

@justingosan
Copy link
Author

Alright my bad. it doesnt happen when creating a new model. It happens during filtering. Try adding this snippet at the end of your code and running it

model.filter({
  username: 'foo'
}).run(function(err, doc){
  console.log(doc);
});

@neumino
Copy link
Owner

neumino commented Aug 13, 2015

Still works for me...

@neumino
Copy link
Owner

neumino commented Aug 13, 2015

Can you provide a full script that fails?

@neumino
Copy link
Owner

neumino commented Aug 13, 2015

(even when multiple documents are returned)

@justingosan
Copy link
Author

In my code there are 2 succeeding filter functions after all placed inside async's so I tried it with your test code. Both filter functions are not necessarily from the same model but should each have results. Sorry I didn't catch this earlier

'use strict';

var thinky = require('thinky')({
    host: process.env.THINKY_HOST || 'localhost',
    port: process.env.THINKY_PORT || 28015,
    db: 'inventerio_test'
});
var type = thinky.type;

var model = thinky.createModel('User', {
    type: thinky.type.string().default('User'),
    id: thinky.type.string(),
    username: thinky.type.string(),
    password: thinky.type.string(),
    first_name: thinky.type.string(),
    last_name: thinky.type.string(),
    email: thinky.type.string(),
    role: thinky.type.string(),
    organization_id: thinky.type.string(),
    date_modified: thinky.type.date().default(thinky.r.now()),
    date_created: thinky.type.date().default(thinky.r.now()),
    isDeleted: thinky.type.boolean().default(false)
}, {
    enforce_extra: 'remove'
});

var Organization = thinky.createModel('Organization', {
    id: type.string()
});

model.belongsTo(Organization, 'organization', 'organization_id', 'id');

model.pre('save', function(next) {
    this.date_modified = thinky.r.now();
    next();
});

model.post('save', function(next) {
    delete this.password;
    next();
});

model.post('retrieve', function(next) {
    delete this.password;
    next();
});

var doc = new model({
    username: 'fooz1',
    password: '1234'
});

doc.save().then(function() {
    model.filter({
        username: 'fooz1' //can be any model but should have result
    }).run(function(err, doc) {
        console.log(err, doc);
        model.filter({
            username: 'fooz1'
        }).run(function(err, doc) {
            console.log(err, doc);  //can be any model but should have result
            process.exit(0);
        });
    });
}).error(function(error) {
    console.log(error);
    process.exit(1);
});

@neumino
Copy link
Owner

neumino commented Aug 13, 2015

Fixed in 2.1.2

@justingosan
Copy link
Author

Thank you!

@justingosan
Copy link
Author

Seems like I spoke too soon. When I run the above code snippet on [email protected], the 2 filter results return undefined:

Creating a pool connected to 192.168.99.100:28015
null undefined
null undefined

Same with the code I'm working on now.

@neumino
Copy link
Owner

neumino commented Aug 14, 2015

Fixed in 2.1.3 -- sorry the async retrieve hook wasn't fully tested...

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

No branches or pull requests

2 participants