Meteor add additional fields to user account at root level

1.7k views Asked by At

How can I add additional fields into the user collection. I understand the options object allows four fields - username, email password and profile. So on Accounts.onCreateUser, is there a way to add additional fields at root level (not inside the profile field)?

As of now, the solution is adding the fields in profile with Accounts.createUser, copying this field to root level and then deleting the field in the profile with Accounts.onCreateUser. This is done for 'userType' in my example below

Client.js

Template.joinForm.events({
'submit .form-join': function(e, t) {
    e.preventDefault();
    var firstName = t.find('#firstName').value,
    lastName = t.find('#lastName').value,
    email = t.find('#email').value,
    password = t.find('#password').value,
    username = firstName + '.' + lastName,
    profile = {
            name: firstName + ' ' + lastName,
            userType: selectedUserType // this is copied to root level and deleted from profile.
};

    Accounts.createUser({
        //NEWFIELD1: [],
        //NEWFILED2: [],
        email: email,
        username: username,
        password: password,
        profile: profile
    }, function(error) {
        if (error) {
            alert(error);
        } else {
            Router.go('/');
        }
    });
}
});

server.js

Accounts.onCreateUser(function(options, user) {
if (options.profile) {
if (options.profile.userType) {
  user.userType = options.profile.userType;
  delete options.profile.userType;
}
user.profile = options.profile;
}
return user;
});
2

There are 2 answers

1
David Weldon On

The only other way to set the fields is to update the user document after the account has been created via a method call. For example:

client

var extraFields = {
  newField1: 'foo',
  newField2: 'bar'
};

Accounts.createUser(..., function(err1) {
  if (err1) {
    alert(err1);
  } else {
    Meteor.call('setUserFields', extraFields, function(err2) {
      if (err2) {
        alert(err2);
      } else {
        Router.go('/');
      }
    });
  }
});

server

Meteor.methods({
  setUserFields: function(extraFields) {
    // TODO: change this check to match your user schema
    check(extraFields, {
      newField1: Match.Optional(String),
      newField2: Match.Optional(String)
    });

    return Meteor.users.update(this.userId, {$set: extraFields});
  }
});

The main problem with this approach is that the user can open up the console and invoke the setUserFields method whenever she wants to. That may or may not be a problem depending on your use case. You can always add additional checks to the method to prevent subsequent updates if necessary.

0
meteorBuzz On

I have abled to create additional fields with out any value (null) on the Accounts.onCreateUser.

Please point out any problems with this solution. Remember to publish the additional field.

server.js

Accounts.onCreateUser(function(options, user) {
if (options.profile) {
if (options.profile.userType) {
  user.userType = options.profile.userType;
  delete options.profile.userType;
  user.newfieldone = options.newfieldone; //this is the line to insert new field
  user.newfieldtwo = options.newfieldtwo;
}
user.profile = options.profile;
}
return user;
});


Meteor.publish(null, function() {
// automatically publish the userType for the connected user
// no subscription is necessary
return Meteor.users.find(this.userId, {fields: {newfieldone: 1, newfieldtwo: 1}});
});