scottwrobinson / camo

A class-based ES6 ODM for Mongo-like databases.
556 stars 80 forks source link

Cannot read property 'documentClass' of undefined #35

Closed michaeljota closed 8 years ago

michaeljota commented 8 years ago

I'm doing an API RESTful with camo using nedb as datastorage. The problem I'm facing is, when I update an array inside another array, I can't access that document anymore.

If I restart the server and load the datastorage again, I can access the data again, even the updated one, so it does saved it. How ever, I doesn't seem to be able to read it after.

Here's my code:

To update:

 Classroom.loadOne({_id: req.params.classId})
        .then(function(classroom){
            var shape = Shape.create({
                type: req.body.type
            });
            classroom.whiteboards[classroom.whiteboards.length-1].shapes.push(shape);
            classroom.save()
                .then(classroom => successHandler (res, shape))
                .catch(err => errorHandler (res, err));
        })
        .catch(err => errorHandler(res, err))

To read:

Classroom.loadOne({_id: req.params.classId})
        .then(classroom => successHandler (res, classroom))
        .catch(err => errorHandler (res, err));

successHandler and errorHandler, just send a response with 200 or 500 status, and jsonp of the document or the error.

Hope can help.

Thanks!

michaeljota commented 8 years ago

Somehow, the document still open after the save() function.

update codes:

    addWhiteboard () {
        this._indexWb = this.whiteboards.push(Whiteboard.create());
    };

    addShape (data) {
        var shape = Shape.create({
            type: data.type
        });
        this._indexShape = this.whiteboards[this._indexWb-1].shapes.push(shape);
    };

    getShape () {
        return this.whiteboards[this._indexWb-1].shapes[this._indexShape-1].toJSON();
    }

    addPoint (point) {
        this.whiteboards[this._indexWb-1].shapes[this._indexShape-1].points.push(Point.create({
            x: point.x,
            y: point.y
        }))
    }

Now they are part of the document.

Am I doing something wrong?

michaeljota commented 8 years ago

I am, at this time, not able to update none of the index. Even if I set them in those function, there are resetting.

scottwrobinson commented 8 years ago

Hi Michael,

A couple quick notes:

When you say "The problem I'm facing is, when I update an array inside another array, I can't access that document anymore", do you mean this line?

classroom.whiteboards[classroom.whiteboards.length-1].shapes.push(shape);

I'll do some testing and see if I can find any problems. It might be helpful if you could post the code for the Classroom and Whiteboard classes. You don't have to post all of it, at least the relevant parts of the schema.

Thanks.

michaeljota commented 8 years ago

Whiteboard, Shape and Point are EmbeddedDocument. I tried to save them, but it throws "save()" it's undefined.

class Classroom extends Document {
    constructor() {
        super();

        this.className = {
            type: String,
            required: true
        };

        this.date = {
            type: Date,
            default: Date.now()
        };

        this.whiteboards = {
            type: [Whiteboard],
            default: [Whiteboard.create()]
        };

        this._indexWb = 0;
        this._indexShape = -1;
    }

    get indexWb () {
        return this._indexShape;
    }

    set indexWb (value) {
        console.log('indexWb: '+value);
        this._indexShape = value;
    }

    get indexShape() {
        return this._indexShape;
    }

    set indexShape(value) {
        console.log('indexShape: '+value);
        this._indexShape = value;
    }

    addWhiteboard () {
        this.indexWb = this.whiteboards.push(Whiteboard.create());
    };

    addShape (data) {
        var shape = Shape.create({
            type: data.type
        });
        this.indexShape = this.whiteboards[this.indexWb].shapes.push(shape);
    };

    getShape () {
        return this.whiteboards[this.indexWb].shapes[this.indexShape].toJSON();
    }

    addPoint (point) {
        this.whiteboards[this.indexWb].shapes[this.indexShape].points.push(Point.create({
            x: point.x,
            y: point.y
        }))
    }
}

This is the current class of the Classroom document. I change things to test. There is no way to update either of the _index, not even with the index get and set (BTW, because of the getters and setters being publics, now the document save them).

I will just move on and use standard Document. I think that may solve the problem. I'll let you know. Thanks!

scottwrobinson commented 8 years ago

Ah, okay, I didn't realize Whiteboard, Shape and Point were EmbeddedDocuments. That makes a lot more sense.

I think you may have found an issue with saving nested arrays, so I'll look in to it.

Thanks!

michaeljota commented 8 years ago

I think it maybe related to a nested arrays of EmbeddedDocuments. I'm unable right now to test it. But next week or so, I'll help you properly reporting a playable scenario.

scottwrobinson commented 8 years ago

Found the issue. You're right, there is a problem saving/loading deeply nested EmbeddedDocuments. I'll be committing the fix shortly.

Thanks for pointing this out!

michaeljota commented 8 years ago

Glad I could help.