I have no idea what's going wrong in my app. I'm trying to update a user profile. If a user has already a profile, it should display the current values of the profile. I have a SimpleSchema attached to the user collection.
<template name="updateCustomerProfile">
<div class="container">
<h1>Edit User</h1>
{{#if isReady 'updateCustomerProfile'}}
{{#autoForm collection="Users" doc=getUsers id="profileForm" type="update"}}
<fieldset>
{{> afQuickField name='username'}}
{{> afObjectField name='profile'}}
</fieldset>
<button type="submit" class="btn btn-primary">Update User</button>
<a class="btn btn-link" role="button" href="{{pathFor 'adminDocuments'}}">Back</a>
{{/autoForm}}
{{else}}
Nothing
{{/if}}
</div>
</template>
I have a template helper:
Template.updateCustomerProfile.events({
getUsers: function () {
//return Users.findOne();
return Meteor.user();
}
});
I have an Autoform hook
AutoForm.addHooks(['profileForm'], {
before: {
insert: function(error, result) {
if (error) {
console.log("Insert Error:", error);
AutoForm.debug();
} else {
console.log("Insert Result:", result);
AutoForm.debug();
}
},
update: function(error) {
if (error) {
console.log("Update Error:", error);
AutoForm.debug();
} else {
console.log("Updated!");
console.log('AutoForm.debug()');
}
}
}
});
Have the following route:
customerRoutes.route('/profile/edit', {
name: "updateCustomerProfile",
subscriptions: function (params, queryParams) {
this.register('updateCustomerProfile', Meteor.subscribe('usersAllforCustomer', Meteor.userId()));
},
action: function(params, queryParams) {
BlazeLayout.render('layout_frontend', {
top: 'menu',
main: 'updateCustomerProfile',
footer: 'footer'
});
}
});
and finally the following publication:
Meteor.publish('usersAllforCustomer', function (userId) {
check(userId, String);
var user = Users.findOne({_id: userId});
if (Roles.userIsInRole(this.userId, 'customer')) {
return Users.find({_id: userId});
}
});
And here is the collection:
Users = Meteor.users;
Schema = {};
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
optional: true
},
lastName: {
type: String,
optional: true
},
gender: {
type: String,
allowedValues: ['Male', 'Female'],
optional: true
},
organization : {
type: String,
optional: true
}
});
Schema.User = new SimpleSchema({
username: {
type: String,
optional: true
},
emails: {
type: Array,
optional: true
},
"emails.$": {
type: Object
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date,
optional: true,
denyUpdate: true,
autoValue: function() {
if (this.isInsert) {
return new Date();
}
}
},
profile: {
type: Schema.UserProfile,
optional: true
},
services: {
type: Object,
optional: true,
blackbox: true
},
roles: {
type: [String],
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
I'm sure the user object is passed in the publication. I can't update the profile: getting the following error (from Autoform debug):
Update Error: Object {$set: Object}
$set: Object
profile.firstName: "test_firstname"
profile.gender: "Female"
profile.lastName: "test_lastname"
profile.organization: "test_organisation
"username: "test_username"
How to go about updating a profile, staring blind....
You need to change your before AutoForm Hooks.
AutoForm.addHooks(['profileForm'], {
before: {
insert: function(doc) {
console.log('doc: ', doc);
return doc;
},
update: function(doc) {
console.log('doc: ', doc);
return doc;
},
},
});
While the after
callback has the js standard (error, result)
function signature, the before
callback has just one parameter, the doc to insert/update. This is why you are always logging an 'error', it is just the doc you want to insert. Also you need to either return it, or pass it to this.result to actually insert/update the object in the db.
From the docs:
var hooksObject = {
before: {
// Replace `formType` with the form `type` attribute to which this hook applies
formType: function(doc) {
// Potentially alter the doc
doc.foo = 'bar';
// Then return it or pass it to this.result()
return doc; (synchronous)
//return false; (synchronous, cancel)
//this.result(doc); (asynchronous)
//this.result(false); (asynchronous, cancel)
}
},
There are a couple small issues so I'm not sure how to tackle your problem, but here's some things to address.
Publish Method
user
is never used. Were you trying to use
it? userId
as a function parameter since you have
access to this.userId
Meteor.publish(null, ...)
so that it overrides the default current user publicationNote: If you remove publish usersAllforCustomer
function, don't forget to remove it from route updateCustomerProfile
Use Global Helper currentUser
Here's how to update your template to use currentUser
instead of getUsers
<template name="updateCustomerProfile">
<div class="container">
<h1>Edit User</h1>
{{#with currentUser}}
{{#autoForm collection="Users" doc=this id="profileForm" type="update"}}
<fieldset>
{{> afQuickField name='username'}}
{{> afObjectField name='profile'}}
</fieldset>
<button type="submit" class="btn btn-primary">Update User</button>
<a class="btn btn-link" role="button" href="{{pathFor 'adminDocuments'}}">Back</a>
{{/autoForm}}
{{else}}
Nothing
{{/with}}
</div>
</template>
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With