How to get just the ID from this._id when this._id returns an object? - meteor

I'm doing the newbie tutorial 'simple-todo' and noticed that once I added security in step 9, I was no longer able to delete tasks created before that.
The issue is that my remove method is checking to make sure that the ID it receives is a string, and the to-do tasks that were made earlier via the console return an object when I use this_.id.
In other words:
Tasks created via the terminal, this._id -> ObjectId("57a128afbe5fd7e7ba9a6fca")
Tasks created with the Tasks.insert method, this._id -> "57a128afbe5fd7e7ba9a6fca"
And the new remove method doesn't like the ObjectId part. How can I get just the ID? I would figure it'd be something like this._id._id, but that's undefined. The workaround was to remove the check from the "remove" method, which is less secure.
Link: https://www.meteor.com/tutorials/blaze/security-with-methods

You can use this._id._str to get the Hex part of the ObjectId.
I would suggest that your method only uses the string, and do a check in the client to see if you need to use this._id or this._id._str

Related

Meteor - check() VS new SimpleSchema() for verifying .publish() arguments

To ensure the type of the arguments my publications receive, should I use SimpleSchema or check()?
Meteor.publish('todos.inList', function(listId, limit) {
new SimpleSchema({
listId: { type: String },
limit: { type: Number }
}).validate({ listId, limit });
[...]
});
or
Meteor.publish('todos.inList', function(listId, limit) {
check(listId, String);
check (limit, Number);
[...]
});
check() allows you to check data type, which is one thing, but is somewhat limited.
SimpleSchema is much more powerful as it checks all keys in a documents (instead of one at a time) and lets you define not only type but also allowed values, define default (or dynamic) values when not present.
You should use SimpleSchema this way:
mySchema = new SimpleSchema({ <your schema here>});
var MyCollection = new Mongo.Collection("my_collection");
MyCollection.attachSchema(mySchema);
That way, you don't event need to check the schema in methods: it will be done automatically.
Of course it's always good practice to use the
mySchema.validate(document);
to validate a client generated document before inserting it in your collection, but if you don't and your document doesn't match the schema (extra keys, wrong types etc...) SimpleSchema will reject the parts that don't belong.
To check arguments to a publish() function or a Meteor.method() use check(). You define a SimpleSchema to validate inserts, upserts, and updates to collections. A publication is none of those - it's readonly. Your use of SimpleSchema with .validate() inline would actually work but it's a pretty unusual pattern and a bit of overkill.
You might find this helpful.
CHECK is a lightweight package for argument checking and general pattern matching. where as SimpleSchema is a huge package with one of the check features. It is just that one package was made before the other.
Both works the same. You can use CHECK externally in Meteor.methods as well. Decision is all yours.
Michel Floyd answer's, made me realize that check() actually sends Meteor.Error(400, "Match Failed") to the client, while SimpleSchema within Methods sends detailed ValidationError one can act upon to display appropriate error messages on a form for instance.
So to answer the question : should we use check() or SimpleSchema() to assess our arguments types in Meteor, I believe the answer is :
Use SimpleSchema if you need a detailed report of the error from the client, otherwise check() is the way to go not to send back critical info.

Meteor parameters and where they come from

I have a question where all the parameters for the meteor functions are coming from? Things like postAttribues, id, postId, limit, etc, etc...
Meteor.publish('newPosts', function(limit) {
return Posts.find({}, {sort: {submitted: -1}, limit: limit});
});
Meteor.publish('singlePost', function(id) {
return id && Posts.find(id);
});
//related to post
Meteor.publish('comments', function(postId) {
return Comments.find({postId: postId});
});
Are they signaled from Mongo DB? It's fine and dandy to memorize these things, but it would be nice to know where these parameters are coming from and what parameters are usually available to me.
I never used any frameworks before, so this may be why I'm confused. I worked exclusively with Javascript before jumping on Meteor.
I also have the same question about Iron Router: When creating a route, we can set a route with a specific Id with /randomName/:_id and the unique code that's responsible for associating the ":_Id" with the actual page is this.params._id. Why and how does the back end associate these things?
I would appreciate any help to help me understand this better.
A meteor find() query follows the syntax find({query}, {options}) defined here: http://docs.meteor.com/#/full/find where the options parameter is an object containing sort, limit, etc... These options look similar to some Mongo operators such as .sort() and .limit() but are defined
The parameters limit and sort are part of the options parameter. It would be useful to review the documentation for Meteor found here: https://docs.mongodb.org/manual/
The parameter postId comes from the way you have defined your objects in your DB. This field is part of your query parameter which specifies what exactly to find in the DB. So by specifying a postId:, Meteor will look through your Comments collection for any containing the postId that you pass. When you pass a string as the query parameter, it is expected that that string is an _id in your collection.
For the parameters being passed into the publication itself see docs.meteor.com/#/full/meteor_subscribe . It comes from the subscription. Basically, you can pass. Parameters between the client and the server this way. To make your publication more robust, you can add parameters as you wish so that the client can specify which 'id' or 'limit' that they want.
As for your iron:router question, I am not sure exactly what you are asking about how the backend associates parameters and the page itself. Perhaps you could be more specific and update your question accordingly

firebase ios gooffline remove observers

Simple question:
Will all obersvers automatically removed when I use goOffline (disconnect to firebase) ?
If not, is there another way to do it, because removeAllOberserves doesn't seem to work or must I keep an array of single handles?
UPDATE
I answer myself.
removeAllOberserves works well, if you call it with the reference you used to set the observer!
Example:
Firebase *userThreadRef;
userThreadRef = [userRef appendPathComponent: ThreadsPath];
[userThreadRef observeEventType: FEventTypeChildAdded withBlock: ^(FDataSnapshot *snapshot) {
...
}];
....
[userThreadRef removeAllObservers];
Do not use a new reference like this:
Firebase *newUserThreadRef = [userRef appendPathComponent: ThreadsPath];
[newUserThreadRef removeAllObservers];
Will all observers automatically removed when I use goOffline (disconnect to firebase) ?
No. Calling goOffline() will not automatically remove observers/listeners.
is there another way to do it, because removeAllOberserves doesn't seem to work or must I keep an array of single handles?
It's hard to say without seeing your code, but likely your expectations are just wrong.
You'll need to call removeAllObservers() on each reference. The All in the method name is for the fact that it removes the observers for all event types, not for all references.

How to modify Database from UI in Meteor App

I am new to meteor and want to modify database document from the user interface,
I understand that we have to use update function but unable to use it as I want to edit the collection from UI on click command, please suggest how to go about it.
Arguments
selector Mongo Selector, Object ID, or String
Specifies which documents to modify
modifier Mongo Modifier
Specifies how to modify the documents
callback Function
**Optional**. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
Please suggest how to use modifier.
Lets put this on an example, using an event handler.
Template.example.events({
'click #updateThis':function(e,t){
var newValue = t.$('.newValue').val(); // taking value from random input
Collection.update({_id:this._id},{$set:{value:newValue}},function(error,result){
if(error){
console.log(error.reason)
}else{
console.log("Nice update")
}
})
}
})
So first the Selector, like it says it should be the ID of the document to modify.
the modifier in this example is the $set more about field update operators here
and the callback is to make it asynchronous, with the 2 parameters i like to use error and result

difficult syncronization problem with FLEX commands (in cairngorm)

My problem, simplified:
I have a dataGrid with a dataProvider "documents"
A column of the datagrid has a labelFunction that gets the project_id field of the document, and returns the project name, from a bindable variable "projects"
Now, I dispatch the events to download from the server the documents and the projects, but If the documents get downloaded before the projects, then the label function gives an error (no "projects" variable)
Therefore, I must serialize the commands being executed: the getDocuments command must execute only after the getProjects command.
In the real world, though, I have dozens of resources being downloaded, and those command are not always grouped together (so I can't for example execute the second command from the onSuccess() method of the first, because not always they must be executed together..)..
I need a simple solution.. I need an idea..
If I understand you correctly, you need to serialize the replies from the server. I have done that by using AsyncToken.
The approach: Before you call the remote function, add a "token" to it. For instance, an id. The reply from the server for that particular call will then include that token. That way you can keep several calls separate and create chains of remote calls.
It's quite cool actually:
service:RemoteObject;
// ..
var call:AsyncToken = service.theMethod.send();
call.myToken = "serialization id";
private function onResult(event:ResultEvent):void
{
// Fetch the serialization id and do something with it
var serId:String = event.token.myToken;
}

Resources