Cannot call method 'create' of undefined - meteor

Here is what I'm getting from the console server side.
I20140516-21:27:12.142(0)? There was an error on this page. Cannot call method 'create' of undefined
I am not finding a good reason why this method isn't defined. I have the balanced-payments-production package from Atmosphere loaded and this includes the balanced.js file and the api export to the server. Any help here is appreciated.
Here is my events.js file
Template.CheckFormSubmit.events({
'submit form': function (e, tmpl) {
e.preventDefault();
var recurringStatus = $(e.target).find('[name=is_recurring]').is(':checked');
var checkForm = {
name: $(e.target).find('[name=name]').val(),
account_number: $(e.target).find('[name=account_number]').val(),
routing_number: $(e.target).find('[name=routing_number]').val(),
recurring: { is_recurring: recurringStatus },
created_at: new Date
}
checkForm._id = Donations.insert(checkForm);
Meteor.call("addCustomer", checkForm, function(error, result) {
console.log(error);
console.log(result);
// Successful tokenization
if(result.status_code === 201 && result.href) {
// Send to your backend
jQuery.post(responseTarget, {
uri: result.href
}, function(r) {
// Check your backend result
if(r.status === 201) {
// Your successful logic here from backend
} else {
// Your failure logic here from backend
}
});
} else {
// Failed to tokenize, your error logic here
}
// Debuging, just displays the tokenization result in a pretty div
$('#response .panel-body pre').html(JSON.stringify(result, false, 4));
$('#response').slideDown(300);
});
var form = tmpl.find('form');
//form.reset();
//Will need to add route to receipt page here.
//Something like this maybe - Router.go('receiptPage', checkForm);
},
'click [name=is_recurring]': function (e, tmpl) {
var id = this._id;
console.log($id);
var isRecuring = tmpl.find('input').checked;
Donations.update({_id: id}, {
$set: { 'recurring.is_recurring': true }
});
}
});
Here is my Methods.js file
function getCustomer(req, callback) {
try {
balanced.marketplace.customers.create(req, callback);
console.log(req.links.customers.bank_accounts);
}
catch (error){
var error = "There was an error on this page. " + error.message;
console.log(error);
}
}
var wrappedGetCustomer = Meteor._wrapAsync(getCustomer);
Meteor.methods({
addCustomer: function(formData) {
try {
console.log(formData);
return wrappedGetCustomer(formData);
}
catch (error) {
var error = "There was an error on this page." + error.message;
console.log(error);
}
}
});

I needed to run balanced.configure('APIKEYHERE'); first, then run the balanced code.

Related

Meteor.call and server methods not working properly

I have this code on my meteor app:
// client side
Template.lead.events({
'submit .insertExternalAccountForm': function (event) {
event.preventDefault();
Session.set('mcsStatus', 'Creating external account ...');
var target = {
code: event.target.code.value,
leadId: event.target.leadId.value,
name: event.target.name.value,
username: event.target.username.value,
password: event.target.password.value,
searchSourceId: event.target.searchSourceId.value,
clientId: event.target.clientId.value,
clientUserId: event.target.clientUserId.value
};
var noFormError = true;
if (target.username.length === 0) {
Session.set("username_error", "Field must not be empty");
noFormError = false;
} else {
Session.set("username_error", null);
}
if (target.password.length === 0) {
Session.set("password_error", "password must not be empty");
noFormError = false;
} else {
Session.set("password_error", null);
}
if (!noFormError) {
return noFormError;
}
Meteor.call('createExternalAccount', target, function (err, res) {
if (err) {
console.error(err);
}
console.log('in meteor call');
Router.go('/' + res.domain + '/' + res.externalId);
});
}
});
//server side
var createExternalAccountSync = function (query, external) {
return models.SearchSources.findOne(query).exec()
.then(function (searchsource) {
external.domain = searchsource.source;
var emr = searchsource.source.split('-');
return models.Organization.findOne({externalId: emr[2]}).exec();
}).then(function (org) {
console.log('after org');
external.organizationId = org._id;
return models.AppUser.findOne({clientId: external.clientId, externalId: external.clientUserId }).exec();
}).then(function (user) {
console.log('after app user');
external.userId = user._id;
external.userIds = [user._id];
return new Promise(function (resolve,reject) {
console.log('saveOrUpdate');
models.ExternalAccount.saveOrUpdate(external, function (err, newE) {
if (err) {
console.error(err)
reject(err);
}
resolve(newE)
});
});
})
.catch(function (e) {
console.error(e);
throw new Meteor.Error(e);
});
};
Meteor.methods({'createExternalAccount': function (data) {
var query = {};
var newExternalAccount = new models.ExternalAccount();
newExternalAccount.username = data.username;
newExternalAccount.password = data.password;
newExternalAccount.externalId = data.username;
newExternalAccount.name = data.name;
newExternalAccount.clientId = data.clientId;
newExternalAccount.clientUserId = data.clientUserId;
newExternalAccount._metadata = { leadId: data.leadId };
if (data.code === 'f') {
query.searchSourceId = '5744f0925db77e3e42136924';
} else {
query.searchSourceId = data.searchSourceId;
}
newExternalAccount.searchSourceId = query.searchSourceId;
console.log('creating external account')
createExternalAccountSync(query, newExternalAccount)
.then(function (external) {
console.log('should return to meteor call');
return external;
})
.catch(function (e) {
console.error(e);
throw new Meteor.Error(e);
});
}
});
The problem that I'm having is that the code on the server side, while it's being called properly, is not triggering the client side meteor.call, there's no console.log output or anything. I believe that the Meteor.wrapAsync method is properly used, but still not showing anything on the client side, and not in fact redirecting where I want the user to go after form submission.
UPDATE
The code has being updated to the newest form, but now I'm getting a weird error on the client, and its actually because the meteor.call method on the template returns neither error or result
Exception in delivering result of invoking 'createExternalAccount': http://localhost:3000/app/app.js?hash=c61e16cef6474ef12f0289b3f8662d8a83a184ab:540:40
http://localhost:3000/packages/meteor.js?hash=ae8b8affa9680bf9720bd8f7fa112f13a62f71c3:1105:27
_maybeInvokeCallback#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3557:21
receiveResult#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3577:30
_livedata_result#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:4742:22
onMessage#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:3385:28
http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:2736:19
forEach#[native code]
forEach#http://localhost:3000/packages/underscore.js?hash=27b3d669b418de8577518760446467e6ff429b1e:149:18
onmessage#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:2735:15
dispatchEvent#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:175:27
_dispatchMessage#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:1160:23
_didMessage#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:1218:34
onmessage#http://localhost:3000/packages/ddp-client.js?hash=27502404fad7fc072e57e8b0b6719f40d92709c7:1365:28
By the code you provided,it could be because you are calling different method.
You defined 'createAccount' but on client side you are calling 'createExternalAccount'

CollectionFS 503 Service Unavailable

I need to upload 'on fly' user's image. But i get error 503 Service Unavailable.
user.js
Meteor.subscribe('userImages');
Template.userProfil.events({
'change [name=userPhotoUpload]': function(event) {
event.preventDefault();
FS.Utility.eachFile(event, function(file) {
var newFile = new FS.File(file);
newFile.metadata = {
createdBy:Meteor.userId(),
}
userImages.insert(newFile, function (err, fileObj) {
if (err){
// handle error
} else {
// handle success depending what you need to do
var currentUserId = Meteor.userId();
var imagesURL = {
"profile.userImg": '/cfs/files/userImages/' + fileObj._id + '/' + fileObj.name()
};
Meteor.users.update(currentUserId, {$set: imagesURL});//there I get url and
}
});
});
}
});
router.js
Router.route('/organizer', {
name: 'userProfil',
template: 'userProfil',
data: function() {
var currentUser = Meteor.userId();
return Meteor.user({_id: currentUser});
}
});
user-img.html
<img src="{{profile.userImg}}">
after uploding image i get this err:
http://localhost:3000/cfs/files/userImages/wNjvF8uuN8j6fd8md/exampl2.jpg 503 (Service Unavailable)
But this path is absolutely correct, and after manual reloading page it's work.
How can I solve this problem?
Ok, I found some solution, but I don't think that it's correct way. Maybe someone have better decision?
Changing:
user.js
'change [name=userPhotoUpload]': function(event) {
event.preventDefault();
FS.Utility.eachFile(event, function(file) {
var newFile = new FS.File(file);
newFile.metadata = {
createdBy:Meteor.userId(),
}
userImages.insert(newFile, function (err, fileObj) {
if (err){
// handle error
} else {
var currentUserId = Meteor.userId();
var intervalHandle = Meteor.setInterval(function () {
console.log("Inside interval");
// changes here:
if (fileObj.hasStored("userImages")) {
//checked if image was stored
var imagesURL = {
"profile.userImg": '/cfs/files/userImages/' + fileObj._id + '/' + fileObj.name()
};
Meteor.users.update(currentUserId, {$set: imagesURL});
// if file has stored, stop interval
Meteor.clearInterval(intervalHandle);
}
}, 1000);
}
});
});
}

Weird undefined error on server

I have the following meteor method
hasNoPendingPayments: function() {
var userId = Meteor.userId();
console.log(userId); <---------------------- correctly logs userId
var user = Users.findOne({_id: userId }, { fields: { services: 0 } });
console.log(user); <-------------------------- logs 'undefined'
return hasNoPendingPayments(user);
},
This private helper I call from the above
hasNoPendingPayments = function(user) {
// console.log('hasNoPendingPayments ');
// console.log(user);
var payments = Payments.find({ userId: user._id, status: {
$in: [Payments.States.PENDING, Payments.States.PROCESSING]}
});
return payments.count() === 0;
};
And I call it from the client here
Template.payments.created = function() {
this.hasNoPendingPayments = new ReactiveVar(false);v
};
Template.payments.rendered = function () {
Session.set('showPaymentRequestForm', false);
var self = this;
Meteor.call('hasNoPendingPayments', function(error, result) {
if (result === true) { self.hasNoPendingPayments.set(true); }
});
...
However, I get an undefined error on the server when I load the template initially (I marked where in code). Although, when I try call the same query on the client with the same userId, i correctly gets the user record
Any idea as to why this is?
Try with this.
Template.payments.rendered = function () {
Session.set('showPaymentRequestForm', false);
var self = this;
if(Meteor.userId()){
Meteor.call('hasNoPendingPayments', function(error, result) {
if (result === true) { self.hasNoPendingPayments.set(true); }
});
}else{
console.log("Seems like user its not logged in at the moment")
}
Maybe when you make the Meteor.call, the data its not ready
Also just to be sure, when you run Users.findOne({_id: userId }, { fields: { services: 0 } }); on console.log what you get?
Maybe the find is wrong or have some typo
update
Router.map(function()
{
this.route('payments',
{
action: function()
{
if (Meteor.userId())
this.render();
} else{
this.render('login') // we send the user to login Template
}
}
}
or waitOn
Router.map(function () {
this.route('payments', {
path: '/payments',
waitOn: function(){
return Meteor.subscribe("userData"); //here we render template until the subscribe its ready
}
});
});
Meteor stores all the user records in Meteor.users collection
so try Meteor.users.findOne({_id: userId }....)
Instead of Users.findOne({_id: userId }, { fields: { services: 0 } });
in your server method

Meteor External API calls works but client gets Undefined

Client Side:
Template.storeInfo.events({
'click #btn-user-data': function(e) {
Meteor.call('callApi', function(err, data) {
$('#result').text(JSON.stringify(data, undefined, 4));
console.log(data); //Not working!!
});
}
});
Server Side:
storeApi.prototype.retrieve = function(endpoint) {
try {
var gotiye = HTTP.get(endpoint);
console.log(gotiye); //Works!
return gotiye;
} catch (err) {
throw new Error("Failed to fetch call GET retrieve from store. " + err.message);
}
};
storeApi.prototype.getStoreInfo = function() {
var url = this.rootApiUrl.replace(this.endpointToken,
this.endpoints.store);
this.retrieve(url);
};
Meteor.methods({
callApi: function() {
var stnvy = new storeApi(Meteor.user().services.store.accessToken);
var data = stnvy.getStoreInfo();
return data;
}
});
Why it works on server side but impossible to use in client side? Is collection the only way to use this?
Forgot to return it at getStoreInfo function return this.retrieve(url); and it works! :)

how to push data back to client in meteor?

I have to make a aggregate query to DB when the user click on a button, however I don't know how to return that result back to the client since I'm doing an asynchronous request, this is part of my code:
//Server side
Meteor.startup(function() {
Meteor.methods({
getAllTotals: function (query){
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var error = result = match = pipeline = '';
var group = {
$group: {
_id: null,
wall_clock: {
"$sum": "$wall_clock"
},
mem:{
"$sum": "$mem"
},
cpu:{
"$sum": "$cpu"
},
io:{
"$sum": "$io"
},
vmem:{
"$sum": "$vmem"
},
maxvmem:{
"$sum": "maxvmem"
}
}
};
if(typeof query.submission_time !== "undefined"){
match = {"$match": {submission_time: query.submission_time}};
pipeline = [match, group];
}else{
pipeline = [group];
}
db.collection("GE_qstat_job_monitor").aggregate(
pipeline,
Meteor.bindEnvironment(
function (error, result){
console.log(result); // <<--- this is OK!
},
function(error) {
Meteor._debug( "Error doing aggregation: " + error);
}
)
);
return result; // <<--- this is empty
}
});
}
any suggestion? :-)
Short answer:
Solution you can find here:
How to get an async data in a function with Meteor
Detailed answer
using Meteor._wrapAsync
var aggregateTotal = function(callback){
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
// ...
db.collection("GE_qstat_job_monitor").aggregate(
pipeline,
function (error, result){
if(error){
callback(error);
}else{
callback(null, result);
}
}
);
}
var aggregateTotalsSync = Meteor._wrapAsync(aggregateTotal);
Meteor.methods({
'getAllTotals': function(){
var result;
try{
result = aggregateTotalsSync();
}catch(e){
console.log("getAllTotals method returned error : " + e);
}finally{
return result;
}
}
});
using Futures (meteorPad example)
//Server side
Meteor.startup(function() {
var Future = Npm.require('fibers/future');
Meteor.methods({
getAllTotals: function (query){
var fut = new Future();
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
// ...
db.collection("GE_qstat_job_monitor").aggregate(
pipeline,
Meteor.bindEnvironment(
function (error, result){
if(error){
fut.throw(error);
}else{
fut.return(result)
}
},
function (exception){
// caught exception is passed to this callback
fut.throw(exception);
}
)
);
return fut.wait();
}
});
}
Easy but a bit dirty way (but not so much if you think well about your architecture) -> send back the result trough Mongo.
You can even do it without Meteor.methods, with the request creation inserted in the database on the client, an observer on the server that check it and does the async task, and then write back the result in the database.

Resources