I'm building a Meteor application and want users to be able to update/set their name. I've got the code set up, and everything seems to be working except that it mysteriously fails on the update. Here's my code:
Template
<template name="_editName">
{{#ionModal focusFirstInput=true customTemplate=true}}
<form id="updateName">
<div class="bar bar-header bar-stable">
<button data-dismiss="modal" type="button" class="button button-clear button-assertive">Cancel</button>
<h2 class="title">Update your name</h2>
<button type="submit" class="button button-positive button-clear">Save</button>
</div>
<div class="content has-header overflow-scroll list">
<label class="item item-input">
<input type="text" id="firstName" placeholder="Given Name">
</label>
<label class="item item-input">
<input type="text" id="lastName" placeholder="Surname">
</label>
</div>
</form>
{{/ionModal}}
</template>
Client-side code
Template._editName.events({
'submit #updateName': function(event, template) {
event.preventDefault();
console.log('Submitted');
var firstName = document.getElementById('firstName').value;
var lastName = document.getElementById('lastName').value;
Meteor.call('editName', firstName, lastName, function(error) {
if (error) {
throw new Error(error.reason);
} else {
Router.go('profile');
}
});
IonModal.close();
IonKeyboard.close();
}
});
Server-side code
Meteor.methods({
'editName': function(firstName, lastName) {
console.log(firstName); // returns expected value
console.log(lastName); // returns expected value
Meteor.users.update({_id: this.userId}, {$set: {
'profile.firstName': firstName,
'profile.lastName': lastName
}});
Meteor.users.findOne({_id: this.userId}, {fields: {
'profile.firstName': 1, _id: 0}}); // returns undefined
}
});
Everything works as it should: On submit, the function gets the field values, calls the method on the server, successfully passing the field values. The update seems to be working as no error is thrown. However, the 'profile.firstName' returns undefined and does not show up in my template.
I'm using the accounts-base package and aldeed:collection2. I have the following schema set up:
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
regEx: /^[a-zA-Z-]{2,25}$/,
optional: true
},
lastName: {
type: String,
regEx: /^[a-zA-Z]{2,25}$/,
optional: true
}
});
I've checked your code and I found multiple issues which need your attention.
The main issues were:
Accounts.onCreateUser(function(options, user) {
// We're enforcing at least a profile skeleton object to avoid needing to check
// for its existence later.
// this file should reside on Server (e.g. [root]/server/accounts.js)
profile = {
firstName: '',
lastName: '',
birthday: '',
sex: '',
grade: '',
country: '',
hostel: '',
house:''
}
user.profile = profile;
return user;
});
Meteor.publish('userProfile', function() {
if(!this.userId) {
return null
} else {
return Meteor.users.find({_id: this.userId}, {
fields: {
username: 1,
'profile.firstName': 1,
'profile.birthday': 1,
'profile.sex': 1,
'profile.grade': 1,
'profile.country': 1,
'profile.hostel': 1,
'profile.house': 1
}
});
}
As a general rule (from my experience at least) I would always start at a bare minimum and avoiding to use complex packages without a solid foundation of the framework at hand. This will save you a lot of debugging and frustration like this in the future.