iamhimadri
iamhimadri

Reputation: 552

How can i add extra field with Autoform inserted data in meteor?

I am using Autoform and Collection2 package in meteor. I am trying to store current logged in userId with inserted data. What is the right way to do that??

// both/collections/myCollection.js

MyCollection = new Mongo.Collection("mycollection");

MyCollection.attachSchema(new SimpleSchema({
    fname : {
        type: String,
        label: "First Name"
    },
    lname : {
        type: String,
        label: "Last Name",
    }
}));

MyCollection.allow({
    insert: function(userId, doc){
        return doc && doc.userId === userId;
    },
    update: function(userId, doc){
        return doc && doc.userId === userId;
    }
})

myTemplate.html

// client/myTemplate.html

<template name="myTemplate">
    {{> quickForm collection="MyCollection" id="insertMyData" type="insert"}}
</template>

myTemplate.js

// client/myTemplate.js

Template.myTemplate.created = function(){

    var postHooks = {
        before: {
            insert: function(doc) {
                if(Meteor.userId()){
                    doc.userId = Meteor.userId();
                }
                return doc;
            }
        }
    }
 AutoForm.addHooks('insertMyData', postHooks);
 }

I remove the insecure package and tried with Writing Data With Allow/Deny (link) but now i am getting error like:

Meteor.makeErrorType.errorClass {error: 403, reason: "Access denied", details: undefined, message: "Access denied [403]", errorType: "Meteor.Error"…} 

Normally Autoform storing data like :

{
    "_id" : "r4uskTttNzADnhZjN",
    "fname" : "firstName",
    "lname" : "lastName"
}

I wanted to store like :

{
    "_id" : "r4uskTttNzADnhZjN",
    "fname" : "firstName",
    "lname" : "lastName"
    "currentUser" : "lsgNynHDrM4Dv9wpH"
}

Upvotes: 1

Views: 473

Answers (2)

ghaliano
ghaliano

Reputation: 415

This is logical as you don't like to inject any extra property to your mongo collection so:

According to the official collection2 doc

you must add the filter option to skip validating those extra field

however this cause another understandable problem when inserting doc

"insert failed: Error: undefined is not allowed by the schema"

Finaly i get it to work with this

MyCollection.insert(task, { validate: false, filter: false });

Important: Make sure you call the check method before!

This is a full working example with validation and redirect using Meteor methods:

Client side

AutoForm.addHooks('taskSubmit', {
  onSubmit: function (insertDoc, updateDoc, currentDoc) {
    Meteor.call('taskInsert', insertDoc, function(error, result) {
      if (error) {
        Errors.throw(error.reason);
      }
      Router.go('taskPage', {_id: result._id});  
    });

    return false;
  }
});

Server side

Tasks = new Mongo.Collection('tasks');

Tasks.attachSchema(taskSchema = new SimpleSchema({
  title: {
    type: String,
    label: "Title"
  },
  body: {
    type: String,
    label: "Description",
    autoform: {
        type: "textarea"
    }
  }
 }
));
Meteor.methods({
  taskInsert: function(task) {
    check(task, Tasks.simpleSchema());

    var user = Meteor.user();
    var task = _.extend(task, {
      userId: user._id, 
      author: user.username,
      submitted: new Date(),
      commentsCount: 0,
      progress: 0
    });

    var id = Tasks.insert(task, { filter: false });

    return {
      _id: id
    };
  }
});

Hope this help someone

Upvotes: 1

Tarang
Tarang

Reputation: 75975

It may be better to do this with an allow rule. You also get the benefit of security with it, in being able to ensure the field is correct with very high certainty.

MyCollection.allow({
    insert: function(userId, doc){
        doc.currentUser = userId;
        return true;
    },
    update: function(userId, doc){
        return doc && doc.currentUser === userId;
    }
});

To strictly solve your problem this should do it:

MyCollection.allow({
    insert: function(userId, doc){
        return doc && doc.currentUser === userId;
    },
    update: function(userId, doc){
        return doc && doc.currentUser === userId;
    }
})

Upvotes: 0

Related Questions