How to add an array attribute to the collection? - meteor

I have global array of type string in my code that am trying to add to my collection.
i manage to add normal global string to the collection this way
previewImage: {
type: String,
autoValue: function() {
return PIurl;
}
}
is it possible to do it with a global array? if no, what alternatives i can use?

If you're just asking for defining a field that is an array of strings with SimpleSchema, you can do it like this:
myArrayOfStringsField: {
type: [String]
}
You can surround any of the valid SimpleSchema types in []'s to make them arrays of that type.

Related

Objects with multiple key columns in realm.io

I am writing an app using the Realm.io database that will pull data from another, server database. The server database has some tables whose primary keys are composed of more than one field. Right now I can't find a way to specify a multiple column key in realm, since the primaryKey() function only returns a String optional.
This one works:
//index
override static func primaryKey() ->String?
{
return "login"
}
But what I would need looks like this:
//index
override static func primaryKey() ->[String]?
{
return ["key_column1","key_column2"]
}
I can't find anything on the docs on how to do this.
Supplying multiple properties as the primary key isn't possible in Realm. At the moment, you can only specify one.
Could you potentially use the information in those two columns to create a single unique value that you could use instead?
It's not natively supported but there is a decent workaround. You can add another property that holds the compound key and make that property the primary key.
Check out this conversation on github for more details https://github.com/realm/realm-cocoa/issues/1192
You can do this, conceptually, by using hash method drived from two or more fields.
Let's assume that these two fields 'name' and 'lastname' are used as multiple primary keys. Here is a sample pseudo code:
StudentSchema = {
name: 'student',
primaryKey: 'pk',
properties: {
pk: 'string',
name: 'string',
lastname: 'string',
schoolno: 'int'
}
};
...
...
// Create a hash string drived from related fields. Before creating hash combine the fields in order.
myname="Uranus";
mylastname="SUN";
myschoolno=345;
hash_pk = Hash( Concat(myname, mylastname ) ); /* Hash(myname + mylastname) */
// Create a student object
realm.create('student',{pk:hash_pk,name:myname,lastname:mylastname,schoolno: myschoolno});
If ObjectId is necessary then goto Convert string to ObjectID in MongoDB

Datatype validation error - MeteorJS/Autoform/SimpleSchema/Embedded Simple Schema

I am using Simple Schema,collection hooks and Autoform packages in Meteor and I am trying to update a Embedded object in my schema in the after update collection hook. I feel I might doing something silly, but was just unable to solve this problem. I am getting the exeption while saving: Exception while invoking method '/providers/update' Error: 0 must be an integer
My schema:
Schemas.Providers = new SimpleSchema({
email: {
type: String,
label: 'Email Address',
autoValue: function() {
if (this.isInsert || this.isUpdate) {
return Meteor.user().emails[0].address;
}
},
autoform: {
afFieldInput: {
type: 'email'
}
}
},
officelocation: {
type: String,
label: 'Location of Office',
optional:true
},
location: {
type: [LocationSchema],
optional:true
}});
The collection hook that works:
Providers.after.update(function (userId, doc) {
var oldDoc = this.previous;
Providers.direct.update({_id: doc._id},{$set: {location:{
type:'Point',
coordinates:[0,0]
}}});
});
The collection hook that does not work.. Ideally I should not be updating after the collection update, but wanted to make sure this works:
Providers.after.update(function (userId, doc) {
var oldDoc = this.previous;
var array=[];
var iArray=doc.officelocation.split(",");
array.push(Number(iArray[1]));
array.push(Number(iArray[0]))
Providers.direct.update({_id: doc._id},{$set: {location:[{
type:'Point',
coordinates:array
}]}});
});
Looking at what you are trying to store, use parseInt instead of Number that you are using. It will return an integer that mongo can store.
The issue is not with the method that you are using. It is with the way you are storing data in mongo. Show us how your LocationSchema looks like.
Detail:
Mongo uses a different number format that what javascript uses. In javascript, a Number can be an integer, a float, a decimal or anything that you want. Mongo has very strict demands when it comes to integer or floats.
Overall, what it means is that if you want to store an accurate decimal number in mongo (which I suspect what you are trying to do), you have to either store it as a string (you loose the ability to do direct mongo operation such as $inc $gt etc) or divide it into two parts and store separably. The third option is to store it as a float which isn't accurate an is only useful if you want some kind of approximate value.

Meteor update a Collection object

in Meteor, I'm having a collection with a Schema, and a number of items are added dynamically.
In this case, I'm dealing with milestones object, and once the user check one off I want to update complete in this Collections item to true (default is false)
Here is my schema
milestones: {
type: Array,
optional: true
},
'milestones.$': {
type: Object
},
'milestones.$.name': {
type: String
},
'milestones.$.hours': {
type: Number
},
'milestones.$.complete': {
type: Boolean
}
How do I write a $set statement for this?
You have an array of objects so, $elemMatch do the trick here.
Projects.update({_id:this._id},{milestones:{$elemMatch:{'milestones.$‌​.name':this.name}},{$set:{'milestone.$.complete':value}}})
So thanks to Aldeed I found a solution - which needs to be called on server side, otherwise it won't let the update happen. Do:
Projects.update({_id:currentPostId, 'milestones.name':name}, {$set:{'milestones.$.complete':true}});
The function is called on the client with Meteor.call with all needed params.
According to your schema you have an object containing an array of objects. So you should write you $set like this:
{$set: {'milestone.$.complete':value}}
This will update the first array element corresponding to the query.
You can find here the official documentation if you want to know more about arrays updates in Mongo.

Meteor AutoForm - Invalid Field Name with Array Index

I've got this in my Simple Schema:
"servicesSelected.0.sku" : {
type: String,
optional: true
},
Basically, I want the sku key in the first array item of servicesSelected to be a String and optional.
Here's my form code, which is for a checkbox.
{{> afFieldInput class="track-order-change" type="checkbox" checkbox="true" template="" name="servicesSelected.0.sku" value="hdrPhotos"}}
The error I get is Invalid Field Name "servicesSelected.0.sku"
As soon as I remove the array index in both the schema and the afFieldInput the error goes away, but the point is to validate the data that is in array index 0...
I am going to assume that it's invalid because in JS you can't have a number as the first character in a key name if you are using dot notation.
But Simple Schema and Autoform do not support square bracket notation...
I'm not sure if SimpleSchema allows you to validate an array like this. A custom validation might be necessary.
I understand that the idea here is that the first element of the array can have the sku property, but others cannot. In this case, try the following method:
servicesSelected: {
type: [selectedServiceSchema],
custom: function() {
for(var i=1; i<this.value.length; ++i) {
if(this.value[i].sku) return "SKU set in the wrong service";
}
},
},

How do I read this JSON string?

I am getting this JSON string from an ASP.Net webservice:
{"d":{"Table":[{"col1":123,"col2":"name","col3":"name","col4":100,"col5":"\/Date(1153033200000)\/"},{"col1":123,"col2":"name","col3":"name","col4":101,"col5":"\/Date(1153033200000)\/"},{"col1":123,"col2":"name","col3":"name","col4":102,"col5":"\/Date(1153033200000)\/"}]}}
In my jQuery how do I reference the Table code so I can loop through the data?
msg.d[i].col1
What am I missing? msg.d.table[i]?
The property d is an object that contains the property Table, which is an array of objects that contain the property col1.
So, you use msg.d.Table to access the array, msg.d.Table[i] to access an item in the array, and msg.d.Table[i].col1 to access the property in the item.
Note that Javascript is case sensetive, so while msg.d.Table works, msg.d.table won't.
This gets the array and loops through it:
var tableArray = msg.d.Table;
$.each(tableArray, function(){
alert(this.col1);
});
msg.d is an object. msg.d.Table will give you what you want.
To iterate:
$.each(msg.d.Table, function(row) {
// Get specific value:
window.alert(row.col1);
// Iterate through all columns:
$.each(row, function(column, value) {
// Do something..
});
});
$.each(msg.d.Table, function(i, val) {
alert(val.col1);
});
I hope this helps!
You can use jQuery's JSON parser:
data = jQuery.parseJSON(JSON_DATA);
And then refer to objects directly via the data variable:
data.my_property

Resources