How to add coordinates in the simple schema

Here is the Simple Schema for coordinates:
{
loc: {
type: Object,
index: ‘2dsphere’,
label: “Location”,
autoform: {
type: “hidden”,
omit: true
}
},
“loc.type”: {
type: String,
allowedValues: [“Point”],
label: “Start location type”
},
“loc.coordinates”: {
type: [Number],
minCount: 2,
maxCount: 2,
decimal: true,
autoValue: function () {
** var lat = document.getElementById(“latitude”);**
** var lng = document.getElementById(“longitude”);**
** var location1 = [lat, lng];**
** return location1;**
}
}
}

I am trying to add values from div ID as latitutde and longitude into the loc.coordinates. But it is not working. It is throwing an error as:
Error: Invalid definition for loc.coordinates field.

Please help me with this. How can add value in the loc.ccordinates automatically.

Thank you in advance.

Do you have aldeed:autoform package added to the project? If not, schema validation will fail on autoform or autoValue fields.

Yes, I have already added the autoForm package ie: aldeed:autoform.

Does your code look exactly as you pasted above? I’ve tested it and SimpleSchema didn’t throw any errors for me.

Edit: Btw, this code:

var lat = document.getElementById("latitude");
var lng = document.getElementById("longitude");

Will not work, because autoValues are computed on the server, so there is no document and DOM to query. From collection2 documentation:

Note that autoValue functions are run on the client only for validation purposes, but the actual value saved will always be generated on the server, regardless of whether the insert/update is initiated from the client or from the server

The error is gone but it is unable to add the value in the loc.coordinates.
Sorry for the trouble.

Okay. Thank you so much for the document link.
If you please tell me as to how should I get the coordinates from another template (which is having a map) to this schema template and add those coordinates automatically in the loc.coordinates field which is hidden?

Normally you utilize a method. On the server side:

Meteor.methods({
  updateLocation: function(locationId, lat, lon) {
    ... validate your inputs, check user permissions, etc ...
    Locations.update({_id: locationId}, {$set: {coordinates: [lat, lon]}});
  }
});

And on the client side, in your template code (probably in some kind of event handler), you call this method like this:

var locationId = ...get location ID from somewhere...;
var lat = document.getElementById("latitude");
var lng = document.getElementById("longitude");
Meteor.call('updateLocation', locationId, lat, lng, function(err, res) {
  ... check if err is not empty, alert user if so ...
});

This example is for updating an existing Locations object. You can similarly create a createLocation method.

Here is a problem that I dont know what will be the syntax for insert. For ID I am using userID and location is just a part of a big schema. Here is the the complete schema:

ComplaintSchema = new SimpleSchema({
prob_cat: {
type: String,
label: “Select a category”,
allowedValues: [‘Road’, ‘Footpath’, ‘Street Light’, ‘Median’]
},
prob_type: {
type: String,
label: “Select the problem”,
allowedValues: [‘Broken’, ‘Absent’]
},
desc: {
type: String,
label: “Description”
},
author: {
type: String,
label: “Author”,
autoValue: function () {
return this.userId;
},
autoform: {
type: “hidden”,
omit: true
}
},
loc: {
type: Object,
index: ‘2dsphere’,
label: “Location”,
autoform: {
type: “hidden”,
omit: true
}
},
“loc.type”: {
type: String,
allowedValues: [“Point”],
label: “Start location type”
},
“loc.coordinates”: {
type: [Number],
minCount: 2,
maxCount: 2,
decimal: true,
autoValue: function () {
var lat = document.getElementById(“latitude”).value;
var lng = document.getElementById(“longitude”).value;
var location1 = [lat, lng];
return location1;
}
},
// Force value to be current date (on server) upon insert
// and prevent updates thereafter.
createdAt: {
type: Date,
label: “Select the date”,
autoValue: function () {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return {$setOnInsert: new Date()};
} else {
this.unset(); // Prevent user from supplying their own value
}
},
autoform: {
type: “hidden”,
omit: true
}
},
// Force value to be current date (on server) upon update
// and don’t allow it to be set upon insert.
updatedAt: {
type: Date,
autoValue: function () {
if (this.isUpdate) {
return new Date();
}
},
denyInsert: true,
optional: true,
autoform: {
type: “hidden”,
omit: true
}
},
// Whenever the “content” field is updated, automatically
// update a history array.
updatesHistory: {
type: [Object],
optional: true,
autoValue: function () {
var content = this.field(“content”);
if (content.isSet) {
if (this.isInsert) {
return [{
date: new Date(),
content: content.value
}];
} else {
return {
$push: {
date: new Date,
content: content.value
}
};
}
} else {
this.unset();
}
},
autoform: {
type: “hidden”,
omit: true
}
},
‘updatesHistory.$.date’: {
type: Date,
optional: true
},
‘updatesHistory.$.content’: {
type: String,
optional: true
}
});

The user give only prob_type, prob_cat and desc fields, rest it is auto generated and thus hidden.
But when the user click on submit button, it should take the coordinates of the same from the previous template.
How should I do it then?

As method, I used this:

Meteor.methods({
    createLocation: function(userID,lat, lng) {
        ComplaintSchema.upsert({_id: userID}, {coordinates: [lat, lng]});
    }
});

For client side, I used this:

'submit': function () {
        var id = Meteor.userId();
        var lat=document.getElementById("latitude").value;
        var lng=document.getElementById("longitude").value;
        Meteor.call('createLocation',id,lat,lng, function(err){
           if(err) console.log("not going in");
        });
        Router.go('/Home');
    }

It is throwing an error. How to insert the values in loc.coordinates, what would be the syntax in that case? Will be it like this:

ComplaintSchema.upsert({_id: userID}, {"loc.coordinates": [lat, lng]});

It has to add the value for loc.type as point also, how will I do that?

Please assist me.

Thank you.
Sorry for the trouble.

First of all, you probably don’t want to insert userID as _id field in your collection. _id is generally a unique identifier for a document in collection. So if you want to store userID’s in your ComplaintSchema, you’ll need to add a field for that.

Secondly, please pay attention to exception messages. In this case, looking at your code, it probably complaints that some values are missing, because you have several non-optional fields in your schema, but you’re only setting loc.coordinates in your upsert query.

Sure, I will not use upsert, but update would solve that issue. But the main issue is that the values are either filled by the user in the form or it is generated as autoValue. Only the location field remains. I have added a quickform in the template which allows user to fill few specific details. But then after user clicks the submit button, location field need to be filed automatically. Hence, in the submit event I have called the Meteor.method.
I hope you got my point.
Thanks.

http://www.curtismlarson.com/blog/2015/12/11/meteor-location-search-engine-mongodb-google-maps/