lukejagodzinski / meteor-astronomy-validators

https://atmospherejs.com/jagi/astronomy-validators
MIT License
11 stars 13 forks source link

Getting an error when manually adding astronomy class #25

Open dovrosenberg opened 8 years ago

dovrosenberg commented 8 years ago

I have a reactive join in a publication where I'm manually adding (using this.added()) an object that is an Astronomy class to the publication. This seems to be working, except that on the client side it is generating the following error:

Uncaught TypeError: self._errors.all is not a function at line 279 of init_module.js

It appears to be when the client is attempting to add the object to the local database, though I'm not sure. Any ideas?

The call stack is: (anonymous function) (init_module.js:279) Tracker.nonreactive (tracker.js:560) events.toJsonValue (initmodule.js:278) (anonymous function) (events.js:42) .every..all (underscore.js:219) .extend.emit (events.js:40) methods.toJSONValue (init_module.js:24) (anonymous function) (ejson.js:168) Meteor._noYieldsAllowed (fiber_stubsclient.js:7) builtinConverters.toJSONValue (ejson.js:167) toJSONValueHelper (ejson.js:230) EJSON.toJSONValue (ejson.js:242) EJSON.clone (ejson.js:489) EJSON.clone (ejson.js:480) (anonymous function) (minimongo.js:706) .each._.forEach (underscore.js:113) LocalCollection.update (minimongo.js:702) Mongo.Collection.self.connection.registerStore.update (collection.js:182) .extend.registerStore._.each.store.(anonymous function) (livedata_connection.js:445) (anonymous function) (livedataconnection.js:1218) .each._.forEach (underscore.js:105) (anonymous function) (livedataconnection.js:1217) .each..forEach (underscore.js:113) .extend._livedata_data (livedata_connection.js:1214) Meteor.connection._livedata_data (ddp_update.js:82) DDPProvider._livedata_data.canFlush (ddp.js:57) onMessage (livedata_connection.js:251) (anonymous function) (stream_clientsockjs.js:172) .each..forEach (underscore.js:105) .extend._launchConnection.self.socket.onmessage (stream_client_sockjs.js:171) REventTarget.dispatchEvent (sockjs-0.3.4.js:87) SockJS._dispatchMessage (sockjs-0.3.4.js:1072) SockJS._didMessage (sockjs-0.3.4.js:1130) SockJS.websocket.that.ws.onmessage (sockjs-0.3.4.js:1277)

Thanks

lukejagodzinski commented 8 years ago

At the beginning I thought that it can't happen outside of the template but I've noticed that I'm using it to stringify validation errors while sending it over DDP. You would have to create reproduction repository, because right now it' hard to predict what can cause this error. It's probably a problem with astronomy.

dovrosenberg commented 8 years ago

Will work on it.

mplatts commented 8 years ago

+1 I was getting this error in production and not development so had to remove the whole package to get it to work properly

lukejagodzinski commented 8 years ago

Reproduction repository could help with solving this issue. Right now I can't check it out.

dnish commented 8 years ago

@jagi Is it possible that Astronomy doesn't work with publish-composite? I'm getting this error when I do the following:

Error:

Exception in queued task: TypeError: doc._errors.all is not a function
    at http://localhost:3000/packages/jagi_astronomy-validators.js?87dd63fbc1f196d4ff37fe6b6dfdfae1d7f2d0a6:631:27

Publish:

Meteor.publishComposite('question', (id) => {
    return {
        find: () => {
            return Questions.find({id: id});
        },

        children: [{
            find: (question) => {
                return Answers.find({questionId: question.id});
            },
            children: [{
                find: (answer) => {
                    return Meteor.users.find(answer.userId);
                },

            }]
        },
            {
                find: (question) => {
                    return Meteor.users.find(question.userId);
                }
            }
        ]
    }
});

Astronomy Class

Question = new Astro.Class({

    name: 'Question',
    collection: Questions,
    fields: {

        title: {
            type: 'string',
            validator: [
                Validators.minLength(20),
                Validators.maxLength(80)
            ]
        },

        desc: {
            type: 'string',
            validator: [
                Validators.minLength(5),
                Validators.maxLength(800)
            ],
            optional: true
        },

        category: {
            type: 'string',
            validator: [
                Validators.required()
            ]
        },

        userId: {
            type: 'string',
            optional: true
        },

        id: {
            type: 'string',
            optional: true
        },

        createdAt: {
            type: 'date',
            optional: true
        }
    },

    relations: {
        user: {
            type:'one',
            class:'User',
            local:'userId',
            foreign:'_id'
        }
    }
});

Template model:

Template.question.viewmodel({

    dbObject: {},
    id() {
        return FlowRouter.getParam("id");
    },

    answers() {
        return Answers.find({questionId:this.id()},{sort:{createdAt:1}});
    },

    onCreated() {

       this.templateInstance.subscribe("question", this.id(), () => {

            this.dbObject(Questions.findOne({id: this.id()}));
        });
    }
});

_Edit: _The Meteor.users collection seems to be the problem, if I don't publish the users, I don't get any error. Also it happens only on several reloads, not everytime. If I get this exception, all my user values are empty (f.e. the username of the question creator).

This is my User class:

User = Astro.Class({
    name: 'User',
    collection: Meteor.users,
    fields: {
        emails: 'array',
        services: 'object',
        createdAt: 'date',
        username: 'string'
    }
});

When I open my console and do Meteor.users.find().fetch() I'll get the following error:

Uncaught TypeError: doc._errors.all is not a function(…)

lukejagodzinski commented 8 years ago

You need to disable transformation function in publication.

Collection.find(selector, { transform: null });

dnish commented 8 years ago

@jagi Thanks, that was it. Just one more question: If I post a new answer, the username on the first answer is always empty. All other answers below show the username. If I refresh the page, I can see all usernames fine. I get the username by relation.

I had this problem before as I didn't checked if the subscription was ready. Now I've added it to the template, but when I add an answer the username is empty, after adding a second answer the username is shown on the second and still empty on the first.

// Edit: It seems like my relations aren't reactive. If I edit the username via Mongo, it doesn't get changed in my template. So the following code will give me a non-reactive object:

relations: {
    user: {
        type:'one',
        class:'User',
        local:'userId',
        foreign:'_id'
    }
},

Is is possible to make it reactive? The only solution I've tried is to define a method:

methods: {
    user() {
        var user = Meteor.users.find(this.userId);
        return user.fetch()[0]; 
    }
  }
lukejagodzinski commented 8 years ago

Hmmm that is probably a bug in relations module that was causing a cache to not be cleared after reactive update. To be honest I don't have time right now to take a look at it as I'm working hard on Astronomy 2.0 which will have relations module built in in 2.1 version. You may try clearing a cache for now by calling:

doc._references = {};

Let me know if it works