I'm invoking my methods from main.js(server) then i used Meteor.call() on main.js(client) and then I recieved an internal error[500]
here is my file structure
this is the console error
main.js(client):
import Tasks from '../imports/api/task.js';
import './main.html';
Template.tasks.helpers({
tasks() {
return Tasks.find({},{sort: {createdAt: -1}})
}
});
Template.tasks.events({
'submit .add-task': function(event){
var name = event.target.name.value;
Meteor.call('addTask', name);
return false;
},
'click .delete-task': function(event){
if(confirm('Delete Task?')){
Meteor.call('deleteTask', this._id)
}
}
});
main.js(server):
import { Meteor } from 'meteor/meteor';
import '../imports/api/task.js';
Meteor.startup(() => {
// code to run on server at startup
Meteor.methods({
addTask: function(name){
if(!Meteor.userId()){
throw new Meteor.Error('Access Denied');
}
Tasks.insert({
name: name,
createdAt: new Date(),
userId: Meteor.userId()
});
},
deleteTask: function(taskId){
Tasks.remove(taskId);
}
});
});
You need to define your methods on server side only.
Meteor.startup(() => {
// code to run on server at startup
if(Meteor.isServer){
Meteor.methods({
addTask: function(name){
if(!Meteor.userId()){
throw new Meteor.Error('Access Denied');
}
Tasks.insert({
name: name,
createdAt: new Date(),
userId: Meteor.userId()
});
},
deleteTask: function(taskId){
Tasks.remove(taskId);
}
});
}
});
Ok I already found out the answer, I though doing import '../imports/api/task.js'; in main.js(server-side) will include all the variables inside of it, the answer is that I need to this import Tasks from '../imports/api/task.js'; can someone explain the differences?
Related
I am very new to Meteor and trying to develop an online synchronous game experiment. Generally, once participants AGREE to the consent form, I want to create a user and add that user into my Players collection.
My consent_page.js looks like this:
import './consent_page.html';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Template } from 'meteor/templating';
import { Meteor } from 'meteor/meteor'
import '../../../api/players/methods.js'
Template.consent_page.events({
'submit .consent-form'(event) {
event.preventDefault();
Meteor.call('players.addPlayer');
FlowRouter.go('/instructions')
}
});
and my players.addPlayer method looks like this
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Players } from './players.js';
import { Random } from 'meteor/random'
Meteor.methods({
'players.addPlayer'() {
console.log('I am in the method');
username = Random.id();
user = create_user(username);
alert(username);
alert(user);
Players.insert({
_id: this.userId,
enterTime: new Date(),
status: 'instructions',
passedQuiz: false,
quizAttempts: 0,
needRematch: false,
condition: 'control'
});
}
});
/*
* Helper functions for the methods
*/
//create user in the server
create_user = function (username) {
return Accounts.createUser({
username: username,
});
};
The collection Players.js has the definition of the collection.
import { Mongo } from 'meteor/mongo'
export const Players = new Mongo.Collection('players');
However, this doesn't work. I do get redirected to the instructions page, but the user doesn't get created .. I get the following error:
Error invoking Method 'players.addPlayer': Method 'players.addPlayer' not found [404]
Although, I get the I am in the method message printed in the console. The alert with the return of create_user is undefined. Also, I want to create the users without a password (how can I do that?).
Accounts.createUser() method is a part of accounts-base package. You need to import that at first. I'm sharing a snippet from my working project. Hope this helps:
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
const bcrypt = require('bcrypt');
Meteor.methods({
'user.create':function(data){
return Accounts.createUser({
name: data.name,
username: data.userId,
password: data.password,
});
}
});
I keep on getting these error messages in my browser console:
Exception in template helper: ReferenceError: "CollectionNames" is not defined
The "CollectionNames" being all the collections I have in my app. I have researched but cant find a suitable solution.
My environment: I am running meteor 1.2
The task.js file is where I define each collection. Below is the code in task.js
/myMeteorApp
--/imports/api/tasks.js
import { Mongo } from "meteor/mongo";
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})] });
buyList = new Mongo.Collection("BuyList");
WhoAreWe = new Mongo.Collection("whoDb");
merchantReviews = new Mongo.Collection("merchantReviews");
Messages = new Meteor.Collection("messages", {transform: function (doc)
{ doc.buyListObj = buyList.find({sessionIDz: {$in: [doc.buyList]}}); return doc; }});
The server is where I publish the collections. Below is the code:
/myMeteorApp
--/server/main.js
import buyList from '../imports/api/tasks.js';
import Messages from '../imports/api/tasks.js';
import Images from '../imports/api/tasks.js';
import WhoAreWe from '../imports/api/tasks.js';
import merchantReviews from '../imports/api/tasks.js';
Meteor.startup(() => {
// code to run on server at startup
Meteor.publish('buyList', function(){
return buyList.find();
});
Meteor.publish('Messages', function(){
return Messages.find();
});
Meteor.publish('Images', function(){
return Messages.find();
});
Meteor.publish('WhoAreWe', function(){
return WhoAreWe.find();
});
Meteor.publish('merchantReviews', function(){
return merchantReviews.find();
});
});
And the client is where I subscribe for the collections. Find below the code:
/myMeteorApp
--/client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
Meteor.subscribe('Messages');
Meteor.subscribe('WhoAreWe');
Meteor.subscribe('Images');
Meteor.subscribe('buyList');
Where am I going wrong. I've been at this for many days now... Kindly help!
The collections must be defined on both the client and the server! Just import your collection names on the client side as well as the server:
import { buyList, Messages, Images, WhoAreWe, merchantReviews } from '../imports/api/tasks.js';
You still have to subscribe to the various publications of course.
It is a naming problem, when you publish the collection, you should refer to the collection name (messages), not the meteor variable (Messages)
Meteor.publish('messages', function(){...
I'm migrating my Meteor application from Meteor 1.2 to Meteor 1.3 and following the guide on http://guide.meteor.com/methods.html#validated-method to create a validated method.
When I call the method, I believe client-side simulation is happening, as I can log out to console, but this is always followed by the error Method '...' not found.
/imports/ui/pages/register.js
import {Meteor} from 'meteor/meteor';
import {Template} from 'meteor/templating';
import {FlowRouter} from 'meteor/kadira:flow-router';
// Methods
import {createAccount} from '/imports/api/accounts/methods.js';
// HTML
import './register.html';
Template.Register_page.events({
'submit form': function(event) {
event.preventDefault();
var user = {
email: $('#email').val(),
password: $('#password').val(),
profile: {
firstName: $('#firstName').val(),
lastName: $('#lastName').val()
}
};
createAccount.call(user, function(err) {
if (err) {
console.error(err);
} else {
console.log('User successfully registered');
FlowRouter.go('Dashboard');
}
});
}
});
/imports/api/accounts/methods.js
import {Meteor} from 'meteor/meteor';
import {ValidatedMethod} from 'meteor/mdg:validated-method';
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
import {Accounts} from 'meteor/accounts-base';
export const createAccount = new ValidatedMethod({
name: 'createAccount',
validate: new SimpleSchema({
email: { type: String },
password: { type: String },
profile: { type: Object },
"profile.firstName": { type: String },
"profile.lastName": { type: String }
}).validator(),
run(user) {
console.log(user);
Accounts.createUser(user);
},
});
Client console
Object {email: "test#mailinator.com", password: "testPassw0rd", profile: Object} methods.js:18
errorClass {error: 404, reason: "Method 'createAccount' not found", details: undefined, message: "Method 'createAccount' not found [404]", errorType: "Meteor.Error"} register.js:28
I believe the reason this wasn't working was because I was not initialising the javascript on the server at startup.
Adding the following fixed the issue:
/imports/startup/server/index.js
import './register-api.js';
/imports/startup/server/register-api.js
import '/imports/api/accounts/methods.js';
I am trying to fetch an entry in a collection with:
client/views/home.js:
criticalCrewNumber = ConfigValues.find({
name: 'criticalCrewNumber'
}).fetch()[0].value;
But I'm getting error:
Uncaught TypeError: Cannot read property 'value' of undefined
If I run the code in the browser console, the desired value is returned as a string.
I have tried various things, e.g. using findOne; placing the code elsewhere in the app; using iron-router waitOn for the subscription to come, etc. Every attempt so far has failed as I end up with undefined.
Here's how the collection is defined, published and subscribed to:
lib/config/admin_config.js:
ConfigValues = new Mongo.Collection("configValues");
ConfigValues.attachSchema(new SimpleSchema({
name: {
type: String,
label: "Name",
max: 200
},
value: {
type: String,
label: "Value",
max: 200
}
}));
both/collections/eventsCollection.js:
if (Meteor.isClient) {
Meteor.subscribe('events');
Meteor.subscribe('config');
};
server/lib/collections.js
```
Meteor.publish('events', function () {
return Events.find();
});
Meteor.publish('config', function () {
return ConfigValues.find();
});
```
Does anyone know what's going on? Thanks.
Consider using ReactiveVar (and Meteor.subscribe callbacks):
criticalCrewNumber = new ReactiveVar();
Meteor.subscribe('config', {
onReady: function () {
var config = ConfigValues.findOne({name: 'criticalCrewNumber'});
if (config) {
criticalCrewNumber.set(config.value);
} else {
console.error('No config value.');
}
},
onStop: function (error) {
if (error) {
console.error(error);
}
}
});
I've been trying to figure this out for quite a while now and feel like I've tried everything.
I have a nested collection under users called details. I had no issues updating the details fields from the client but I obviously want to run the updates through the server for security.
Here's my server code:
//server code
Meteor.methods({
updateProfile : function() {
Meteor.users.update({ _id: Meteor.userId() }, { $set: { "details.phoneNumber" : phoneNumber }
});
}
});
And my client code:
Template.userEdit.events({
'submit updateProfile' : function(e, t){
e.preventDefault();
var firstName = e.target.phoneNumber;
Meteor.call('phoneNumber');
}
});
For now I am publishing/subscribing to the entire users collection:
// Server
Meteor.publish("allUserData", function () {
return Meteor.users.find();
});
// Client
Tracker.autorun(function () {
Meteor.subscribe("allUserData");
});
Your server method is called "updateProfile", but you call "phoneNumber" on the client. Meteor methods are called as follows, in your case:
Meteor.call("updateProfile", phoneNumber);
And your server method must accept an argument as input:
Meteor.methods({
updateProfile : function(phoneNumber) {
//...
}
});