Googleplace not saving to collection - meteor

I'm currently using lukemadera:autoform-googleplace to save the users address. When the user saves their address it only saves the fullAddress field in the schema. I thought it broke the address up into its parts; street, state, zip etc. That way you could publish the address parts individually if required. I would like to be able to publish just the state in certain circumstances but I'm not sure how to do that since all I have is a fullAddress field string. Let me know if you need more clarification.
Path: address.js
Template.address.helpers({
optsGoogleplace: function() {
return {
// type: 'googleUI',
// stopTimeoutOnKeyup: false,
googleOptions: {
componentRestrictions: { country:'au' }
}
}
},
});
Path: address.html
{{#autoForm collection="Meteor.users" id="user" doc=currentUser type="update"}}
{{> afQuickField name="profile.address" type="googleplace" opts=optsGoogleplace class="form-control"}}
{{autoForm}}
Path: Schema.js
Schema.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
regEx: /^A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]$/
},
zip: {
type: String,
regEx: /^[0-9]{5}$/
},
country: {
type: String
}
});

If you have it set up correctly, something like this should work:
Schemas = {};
Schemas.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
},
zip: {
type: String,
},
country: {
type: String
},
});
Schemas.MainSchema = new SimpleSchema({
address: {
type: Schemas.Address,
optional: true
}
});
MainSchema = new Mongo.Collection("MainSchema");
MainSchema.attachSchema(Schemas.MainSchema);
MainSchema.allow({
insert: function () { return true; },
update: function () { return true; },
remove: function () { return true; }
});
Maybe check these out:
https://github.com/lukemadera/meteor-autoform-googleplace/issues/24
https://github.com/lukemadera/meteor-autoform-googleplace/issues/25
http://www.curtismlarson.com/blog/2015/12/11/meteor-location-search-engine-mongodb-google-maps/
My only other guess is something is wrong with you google options helper. I'm not using that right now and the above setup works for me.

Related

Update array of objects leads to blank array

Please tell me what I'm missing here. When I update the Array of objects my collection updates with an empty array. I'm using meteor-collection2-core and node-simple-schema.
Path: Method
testArray = [{
"institution": "Swinburn",
"uniqueId": 1501036480813,
"qualification": "Bachelor of Commerce",
"completed": "2017"
}]
ProfileCandidate.update('Ntzj6kE8qZsvSPMEP', {$set: {educationQualifications: testArray}});
Path: Collection
export const ProfileCandidate = new Mongo.Collection('profileCandidate');
const ProfileCandidateSchema = new SimpleSchema({
userId: {
type: String,
regEx: SimpleSchema.RegEx.Id
},
educationQualifications: { type: Array, optional: true },
'educationQualifications.$': { type: Object, optional: true },
'educationQualifications.$.uniqueId': { type: Number, optional: true },
'educationQualifications.$.institution': { type: String, optional: true },
'educationQualifications.$.qualification': { type: String, optional: true },
'educationQualifications.$.completed': { type: String, optional: true }
});
ProfileCandidate.attachSchema(ProfileCandidateSchema);
In your method, try this:
ProfileCandidate.update({userId: 'Ntzj6kE8qZsvSPMEP'}, {$set: {educationQualifications: testArray}});

Meteor password validation

I'm struggling to figure out how to make password validation with my user Schema, that's how I've being doing so far:
This is the schema:
Schema = {};
Schema.UserProfile = new SimpleSchema({
//LOTS OF FIELDS WORKING FINE
});
Schema.User = new SimpleSchema({
username: {
type: String,
optional: true
},
emails: {
type: Array,
},
"emails.$": {
type: Object
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schema.UserProfile,
label: "Perfil",
optional: false
},
services: {
type: Object,
blackbox: true
},
"services.$": {
type: Object,
blackbox: true
},
"services.$.password": { // IS IT RIGHT?
type: String,
label: "Senha",
min: 8
},
roles: {
type: String,
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
And this is how I'm saving:
let company = {};
company = {
email: $('#email').val(),
password: $('#password').val(),
roles: 'company',
profile: companyProfile
}
Meteor.call('saveUser', company, function(error, result) {
if ( error ) {
console.log(error);
}
}
Meteor.methods({
saveUser: function(data) {
return Accounts.createUser(data);
}
});
I'm still a beginner, so I'm probably messing something up here. When I try to create the user, if there is an issue with any of the fields, the validation throws an error as expected. However no error is thrown in case I miss the password, any ideas of what I'm doing wrong here?
------------------------------- UPDATE ----------------------------------
Thanks #aedm for your answer. I really wish I could have something like this to verify the password and password confirmation:
password: {
type: String,
label: "Senha",
min: 8
},
password_confirmation: {
type: String,
label: "Confirmação de Senha",
min: 8,
custom: function () {
if (this.value !== this.field('password').value) {
return "passwordMismatch";
}
}
},
I guess it's not possible then, is it?
Meteor only stores a bcrypt hash for the password, it's always longer than 8 characters.
Instead, your saveUser method should throw an error when the password criteria isn't met.
Meteor.methods({
saveUser: function(data) {
if (data.password.length < 8) throw new Meteor.Error("Password too short");
return Accounts.createUser(data);
}
});
I'd try to avoid defining a schema for users, Meteor handles it pretty well without one, and it's not trivial how to do it properly.

meteor - lukemadera:autoform-googleplace

I've installed lukemadera:autoform-googleplace package and followed the usage instructions. When I run the application the address field doesn't auto populate as I type. I get an error in console (Exception in template helper: ReferenceError: EJSON is not defined) can someone please tell me what I'm missing.
Path: Layout.html
<head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
</head>
Path: Schema.js
Schema.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
regEx: /^A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]$/
},
zip: {
type: String,
regEx: /^[0-9]{5}$/
},
country: {
type: String
}
});
Schema.UserProfile = new SimpleSchema({
address: {
type: Schema.Address,
optional: true
}
});
Path: personalDetails.js
<template name="personalDetails">
{{#autoForm collection="Meteor.users" id="candidateProfile" doc=currentUser type="update"}}
{{> afQuickField name="profile.address" type="googleplace" opts=optsGoogleplace}}
{{/autoForm}}
</template>
Path: personalDetails.js
Template.personalDetails.helpers({
optsGoogleplace: function() {
return {
// type: 'googleUI',
// stopTimeoutOnKeyup: false,
// googleOptions: {
// componentRestrictions: { country:'us' }
// }
}
}
});
FYI, just in case someone else gets this error, you need to install ejson.

Meteor UI helper with Meteor.users

I have an app in which I'm using a template helper. I have the following code:
UI.registerHelper('ProfileNameByUserId', function(userid) {
console.log('Userid: ' + userid);
var user = Meteor.users.findOne({'_id': userid});
console.log.log('User:' + user);
return user.username
});
I'm calling this in my template as follows:
{{#each getDocuments}}
{{ProfileNameByUserId userid}}
{{/each}}
and in the template helper:
Template.documentsIndex.helpers({
getDocuments: function () {
return Documents.find({}, { sort: { createdAt: -1 }});
}
});
The publish and subscribe are as follows:
Routes.route('/documents', {
name: 'documents',
subscriptions: function (params, queryParams) {
this.register('documentsIndex', Meteor.subscribe('documents'));
},
action: function (params, queryParams) {
.....
});
}
});
Meteor.publish('documents', function () {
return Documents.find({})
});
I'm sure the userId is passed on, as a console.log statement shows the correct id. The issue is that the user is 'undefined' so it can't find the username.
I'm using SimpleSchema to define a users schema which looks as follows:
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
},
});
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);
});
Replacing Meteor.users.findOne() in the template helper with Users.findOne() does not work either.
Any idea why user remains undefined?
You need to add a publication and subscription for the users that you want to show.
In the most general case in which all users are published:
Meteor.publish('allUsers', function () {
return Meteor.users.find();
});
Subscribe to this in your route and you will not have the user undefined in your helper.
Note that you should only publish the users that you need, but since I do not know you application structure I cannot give you a query for that.

Meteor collection2 not updating

I'm having some trouble with updating a user account. I use the following schema (collection2):
lib/collections/users.js
Users = Meteor.users;
var Schemas = {};
Schemas.User = new SimpleSchema({
gender: {
type: Number,
min: 1
},
s_gender: {
type: Number,
min: 1,
optional:false
},
picture: {
type: String,
custom: function() {
var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
var value = this.value.replace("data:image/png;base64,","");
if(!base64Matcher.test(value))
{
return 'no picture';
}
else
{
return true;
}
}
}
});
Users.attachSchema(Schemas.User);
Now I do the update with the following code:
client/templates/start.js
Users.update({_id: Meteor.userId()}, {
$set: {picture: picture, gender: gender, s_gender: s_gender}
}, {validationContext: "updateUser"}, function (error, result) {
if (error) {
errorObjs = Users.simpleSchema().namedContext("updateUser").invalidKeys();
console.log(errorObjs);
}
console.log(result);
});
The validation passes, but I only get a "0" in results (errors are null) - the update isn't working. Errors are shown if I have an empty field, so the validation is working well. If I detach the schema, the update works fine.
Did I forget something here or why isn't he updating when validation passes?
// Edit: Also I see, that Meteor doesn't create users anymore.
I believe you need to use Users.profile.foo instead of Users.foo, because Users is a special meteor collection and you can only save new fields inside the profile field. Try using Simple Schema/Collection 2 suggested User schema as a starting point (I'll copy it bellow). Notice the "profile schema" is loaded before the user schema:
Schema = {};
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
},
birthday: {
type: Date,
optional: true
},
gender: {
type: String,
allowedValues: ['Male', 'Female'],
optional: true
},
organization : {
type: String,
regEx: /^[a-z0-9A-z .]{3,30}$/,
optional: true
},
website: {
type: String,
regEx: SimpleSchema.RegEx.Url,
optional: true
},
bio: {
type: String,
optional: true
}
});
Schema.User = new SimpleSchema({
username: {
type: String,
regEx: /^[a-z0-9A-Z_]{3,15}$/
},
emails: {
type: [Object],
optional: true
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schema.UserProfile,
optional: true
},
services: {
type: Object,
optional: true,
blackbox: true
}
});
Meteor.users.attachSchema(Schema.User);
source: https://github.com/aldeed/meteor-collection2

Resources