Meteor JS: How do I insert a document into a collection, but only on the client-side?
collections, javascript, meteor
Solution
You should store the temporary tag (and probably your `isEditing` var) in `Session`:
Session.set("isEditing", true);
Session.set("newTag", {x:mouseX, y:mouseY});
You can also create a local collection by passing `null` instead of a collection name when initializing it. However, `Session` should work for what you're doing. Check out the leaderboard for an example.
Edit:
<figcaption class="tags">
{{#each tags}}
{{> tag}}
{{/each}}
{{#with newTag}}
{{> tag}}
{{/with}}
</figcaption>
Template.image.newTag = function() {
return Session.get("newTag");
}
Problem
I'm new to Meteor and building a simple app to learn the framework. The app I'm building let's you place words on an image of a kitten. The desired behavior is this: A user clicks anywhere on the kitten, and a contenteditable element appears letting the user enter text. Clicking outside of the element saves the element, and it remains in place. The problem I'm running into: If I have two browser windows opened with the app, and I click on one kitten in one window, an empty field appears in both windows. Ideally, the empty field would appear only on the window I clicked on. Once a word is saved, then in should be visible in both windows. My question: Is there a way to `insert` a document into a collection on the client-side only, and then use `upsert` later to add the document to servert-side collection? Here's what I tried: I created a stub method that exists only on the client-side for inserting the document. The problem with this, is that when I click on the image, an empty field appears for a split-second, and then disappears again. Here's the code: image-tags.js ``` if (Meteor.isClient) { var isEditing; Template.image.image_source = function () { return "http://placekitten.com/g/800/600"; }; Template.tag.rendered = function(){ var tag = this.find('.tag'); if (isEditing && !tag.innerText) { tag.focus(); } } Template.image.events({ 'click img' : function (e) { if (isEditing) { isEditing = false; } else { isEditing = true; var mouseX = e.offsetX; var mouseY = e.offsetY; // Tags.insert({x:mouseX, y:mouseY}); // Insert tag on the client-side only. // Upsert later when the field is not empty. Meteor.call('insertTag', {x:mouseX, y:mouseY}); } }, 'click .tag' : function (e) { isEditing = true; }, 'blur .tag' : function (e) { var currentTagId = this._id; var text = e.target.innerText; if(text) { Tags.upsert(currentTagId, {$set: {name: text}}); } else { Tags.remove(currentTagId); } } }); Template.image.helpers({ tags: function() { return Tags.find(); } }); // Define methods for the collections Meteor.methods({ insertTag: function(attr) { Tags.insert({x:attr.x, y:attr.y}); } }); } // Collections Tags = new Meteor.Collection('tags'); ``` image-tags.html ``` <head> <title>Image Tagger</title> </head> <body> {{> image}} </body> <template name="image"> <figure> <img src="{{image_source}}" /> <figcaption class="tags"> {{#each tags}} {{> tag}} {{/each}} </figcaption> </figure> </template> <template name="tag"> <div class="tag" contenteditable style="left: {{x}}px; top: {{y}}px;"> {{name}} </div> </template> ```