What I want to do is update a field called name, by means of its identification I do the query of the field.
When doing the name query, it takes me to the template called updatename.
The problem is that when I save the changes it tells me this message in the console.
Exception while invoking method 'name.update' Error: Invalid modifier. Modifier must be an object.
Client
updatename.html
<template name="updatename">
<form class="editor-container">
<input class=“save” type="text" id="card" value=“{{name}}”>
<button type="button" class=“save” id="save">save</button>
</form>
</template>
updatename.js
Template.updatename.events({
'click .save’: function (e, t) {
e.preventDefault();
FlowRouter.watchPathChange();
var name = FlowRouter.current().params._id;
var name = $('#card').val();
Meteor.call('name.update',name);
FlowRouter.go('/');
}
});
Server
name.js
Meteor.methods({
'name.update'( name) {
Name.update({
$set: {
nam: name
}
});
}
});
It looks like you're not telling it what to update in the Publications.update({}) - note that you need an selector and a modifier.
It should look more like:
Publications.update(
{_id: "SOMEID"}, <--- missing bit
{$set: {pub: publication}}
)
Related
I want to update only the name field, the problem with the code I have is that if I update a document, all the mongo documents are updated.
As I update a document in specific, I must admit that I am new to this mongo so any help I thank you.
Client
updatename.html
<template name="updatename">
<form class="editor-container">
<input class=“save” type="text" id="card" value=“{{name}}”>
<button type="button" class=“save” id="save">save</button>
</form>
</template>
updatename.js
Template.updatename.events({
'click .save’: function (e, t) {
e.preventDefault();
FlowRouter.watchPathChange();
var name = FlowRouter.current().params._id;
var name = $('#card').val();
Meteor.call('name.update',name);
FlowRouter.go('/');
}
});
Server
name.js
Meteor.methods({
'name.update'( name) {
Name.update({
Name.update({},{ $set: { nam: name }},{multi:true})
});
}
});
I recommend few improvisations over your Meteor code.
Atleast use Title Case/ CamelCase for better readability of the template name and Meteor Methods for other developer.
use submit .formClassName instead of using click .save, also specifiy parameter name with sincerity like function (event, template)
When you updating document for logged user and not other user, as dmayo mentioned in the code use Name.update({_id: Meteor.userId()},{ $set: {nam: name}}), but there is no sense of specifying { multi: true } when you know that there is going to be only 1 record when you are updating. You can use { multi: true } when you desire to impact many records based on criteria that are definitely going to return more than 1 record.
use check(name, String) in Meteor.method call to ensure what you are sending to the server is eligible for further operations.
Use aldeed autoforms when you know there is no out of the box implementation and is going to be simple.
Below is the improvised code for better readability and up to standards
Client
update-name.html
<template name="UpdateName">
<form class="editorContainerForm">
<input type="text" id="card" value=“{{name}}”>
<button type="submit">Save</button>
</form>
</template>
update-name.js
Template.UpdateName.events({
'submit .editorContainerForm’: function (event, template) {
event.preventDefault();
FlowRouter.watchPathChange();
var name = FlowRouter.current().params._id;
var name = $('#card').val();
Meteor.call('updateName',name, function(error, response){
if(error){
// Show some BERT ERROR message for better user experience
// use "meteor add themeteorchef:bert" to add package
} else {
// Show some BERT SUCCESS message for better user experience
});
FlowRouter.go('/');
}
});
Server
name.js
Meteor.methods({
updateName( name ) {
check(name, String);
Name.update({ _id: Meteor.userId },{ $set: { name: name }});
// Use below code only if you know there can be multiple records for same ID
// Name.update({ _id: Meteor.userId },{ $set: { name: name }}, { multi: true });
}
});
In your name.js file (on the server) your mongo query is empty, so when mongo queries your database, it matches all of the documents/records.
Name.update(query, changes, options)
That is the format per the mongo docs. You need to have a unique identifier. Your form is saving a "name", and that's what you are passing to the Meteor.method, but you're not telling the method who's changing their name. If the user is logged in, then you can just use the meteor unique id Meteor.userId()
Name.update({_id: Meteor.userId()},{ $set: {nam: name}},{multi:true})
Also, your option multi:true says to update any and all documents that match the query. If in your original method as written, you had multi:false (the default) then only one document would have been updated (but probably not the one you wanted as the first match would have been updated because of your empty query field.
Mongo docs: https://docs.mongodb.com/manual/reference/method/db.collection.update/
Metor docs: https://docs.meteor.com/api/collections.html#Mongo-Collection-update
I created a collection called Stampest that stores a reference of an uploaded image and a title string, created by a user. Using the ostrio:autoform package.This package creates a collection called Images where all the user uploaded images are stored and hense referenced to/from.
When I query mongo in my terminal using
db.stampest.find({})
I get the entries
Which shows that there are documents in the database, in the Stampest Collection. But the PROBLEM is that when I look at the collection in Meteor Toys debug, it says its empty, and when I insert a document, in this case, the image and the title, the collection changes to 1 for a split second and geos back to 0. There are no error from the terminal or console
As a consequence, I cannot access these documents, what can I do?
This is the schema.js
Schemas = {};
Stampest = new Meteor.Collection('stampest');
Stampest.allow({
insert: function (userId, doc) {
return userId;
},
update: function (userId, doc, fields, modifier) {
// can only change your own documents
return doc.userId === userId;
},
remove: function (userId, doc) {
// can only remove your own documents
return doc.userId === userId;
}
});
Schemas.Stampest = new SimpleSchema({
title: {
type: String,
max: 60
},
picture: {
type: String,
autoform: {
afFieldInput: {
type: 'fileUpload',
collection: 'Images',
// uploadTemplate: 'uploadField' // <- Optional
// previewTemplate: 'uploadPreview' // <- Optional
}
}
}
});
Stampest.attachSchema(Schemas.Stampest);
The publish is like this:
Meteor.publish('stampest', function () {
return Stampest.find({author: this.userId}).fetch();
console.log(Stampest.find());
});
The user inserts the image and the title like this:
<template name="createStamp">
<div class="grid-block">
<div class="grid-container">
<div class="upload-img">
{{file.original.name}}
</div>
<div class="new-stamp-container">
{{> quickForm collection="Stampest" type="insert" id="insertStampForm" class="new-stamp-form"}}
</div>
</div>
</div>
</template>
From what I see in your code, you are returning an Array of db items and not a Cursor in your code.
If you take a look at https://docs.meteor.com/api/pubsub.html, you'll notice that regular publications return simple cursors or array of cursors but never your fetched data.
edit: also, the console.log in your publication will never be interpreted as it returns on the previous line.
Probably a bad title, I don't know how to precisely describe this.
Template.body.helpers({
messages: function () {
return Messages.find({}, {
sort: {createdAt: -1}
});
}
});
This is the code I have.
On the client side, it takes
{{#each messages}}
<span class="text"> {{messageText}} </span>
{{/each}}
Each message contains "text" and "username".
How would I go about, in the "return Messages" part, modifying what it returns?
So I would do something like
Template.body.helpers({
messages: function () {
Messages.find().forEach(function(thismsg){
messageText = slugify(thismsg.messageText)
};
}
});
Get messages, modify the fields and then return them. Could I perhaps do this in subscriptions instead? Please help.
You can pass your message in the helper and then you can modify the message and pass back to the template like this.
Your template code.
{{#each messages}}
<span class="text"> {{slugifyMessage text}} </span>
{{/each}}
You helper code.
Template.body.helpers({
messages: function () {
return Messages.find({}, {
sort: {createdAt: -1}
});
}
slugifyMessage: function(messageText){
return slugify(messageText);
}
});
Please make sure your text that I am passing to slugifyMessage will same name as database you mentioned that you have only two field named username and text, So I took text you can replace this with your doc field that you want to modify.
In my Meteor app, I am publishing:
ForeignVisaTypes = new Mongo.Collection("foreignVisaTypes");
if (Meteor.isServer) {
Meteor.publish("foreignVisaTypes", function () {
return ForeignVisaTypes.find();
});
}
...and subscribing to:
if (Meteor.isClient) {
Meteor.subscribe("foreignVisaTypes");
. . .
}
...a Collection which is populated with values.
However, this attempt to populate the select is failing:
<select name="selvisatype" id="selvisatype" title="Please select a visa type">
{{#each foreignVisaTypes}}
<option value={{value}}>{{display}}</option>
{{/each}}
</select>
Why is it failing?
It's not enough to subscribe to a collection. It will not be available directly in spacebars as a helper. So you still need to define a helper to expose it.
Just add this to your client code and things should start working (replace myTemplate with the name of your template):
Template.myTemplate.helpers({
foreignVisaTypes: function() {
return ForeignVisaTypes.find();
}
});
How can I query a field in an object? My html retrieves all the objects in array called 'postcards'
Meteor.user.profile.postcards [
{
_id: 84fh83f,
field_one: "a name",
field_two: " winter whether",
field_three: " lost more writing"
},
{
_id: 6jsf58s,
field_one: "another name",
field_two: " topical issues ",
field_three: " lost more writing"
}
]
Note: I used random.Id() so each object in the array can be uniquely identified.
Setting a session value to this._id when the user is focused on the input field will retrieve this unique id, however, I would like to query the actual field in focus. The value in these fields are projected within the text input area by using the spacebars syntax within the html.
Can I somehow assign the name within the curly braces of the value attribute to a variable? Then query?
Is there a whole new way to achieve this?
I want to update that specific field in this object instead updating the entire object.
HTML:
{{#with currentUser.profile}}
{{#each postcards}}
<input id="one" value="{{field_one}}" type="text">
<input id="two" value="{{field_two}}" type="text">
<input id="three" value="{{field_three}}" type="text">
{{/each}}
{{/with}}
client.js
Within events, I would like to update the field on focus upon keyup.
Templates.myTemplate.events({
'keyup input[type=text]': _.throttle(function(event) {
Meteor.users.update(this._id, {$set: {**fieldbeingedited**: event.target.value}});
}, 500);
});
What you want to have is an ES6 capability named 'Computed property names'.
This is what is looks like :
var x = 'hello',
obj = {
[x]: 'world'
};
console.log(obj); // Object {hello: "world"}
You have two options :
- you use the meteor harmony package to transpile your es6 to es5 (https://github.com/mquandalle/meteor-harmony)
- you build your object first
To build you object first :
var obj = {};
obj[ this.targetField ] = event.target.value
Meteor.users.update(this._id, {$set: obj});