Meteor.call issue in Meteor? - javascript

I need to know about the usage of Meteor.call. I did a simple example as shown below. The problem is that it never goes to insertDetails(). Can you please check the below code and suggest me what to do so that I don't get the Match Failed error.
Client.JS
Meteor.methods
({
//this method doesn't cal when using meteor.cal
insertDetails : function(adData, callback)
{
console.log(">>>>>>>>>>>>>>>>>>> ******* insertDetails ");
checkFields(adData);
var fields =
{
userID: adData.UserID,
fname: adData.fname,
lname: adData.lname,
dob: adData.dob
};
return Client.insert(fields, callback);
}
});
// SERVER-SIDE HELPERS ************************************
var nonEmpty = Match.Where(function(x) {return !!x;});
var checkFields = function(adData)
{
console.log(">>>>>>>>>>>>>>>>>>> checkFields ");
check(adData.userID, nonEmpty);
check(adData.fname, nonEmpty);
};
Insert.js
if (Meteor.isClient)
{
Template.hello.events({
'submit #addnewuserdetails': function (e,t)
{
if (typeof console !== 'undefined')
console.log(">>>>>>>>>>>>>>>>>>> Add button in details ");
e.preventDefault();
saveClientDetails();
}
});
}
var saveClientDetails = function()
{
console.log(">>>>>>>>>>>>>>>>>>> saveClientDetails ");
var fields = {
//ownerId: Meteor.userId(),
UserID : $('#userid').value
,fname : $('#fname').value
,lname :$('#lname').value
,dob : $('#dob').value
};
console.log(">>>>>>>>>>>>>>>>>>> fields.UserID "+fields.UserID);
//here cal to above insertDetails()
Meteor.call("insertDetails", fields, function(err, result)
{
if (!err)
{
console.log(">>>>>>>>>>>>>>>>>>> saveClientDetails Success");
}
else
{
console.log(">>>>>>>>>>>>>>>>>>> saveClientDetails ERROR "+err.reason);
}
});
};

The Match Failed error points to invalid data being rejected by your check function. My guess is that the problem is with user id: when you call the method you use UserID parameter, but then you check lowercase userID. Try fixing that and see whether it works. Also, try commenting out check call and see whether the rest of code is running. Also, how do you verify that the method was not called? Notice that log should be visible in the server console.

Related

Javascript IndexedDB example encountering transaction and db variable not defined

I'm learning javascript indexedDB and so, I followed an example from Javascript tutorial - https://www.javascripttutorial.net/web-apis/javascript-indexeddb/.
I followed the example to understand how it works. Below are my codes.
<html>
<head>
<title>Indexed Database</title>
</head>
<body>
<script>
if (!window.indexedDB) {
console.log("Your browser doesn't support IndexedDB");
}
const request = indexedDB.open("indexedDatabase", 3);
request.onerror = (event) => {
console.error ("Database error: ${event.target.errorCode}");
};
request.onsuccess = (event) => {
console.log("success: " + request);
insertContact(db, {
email: 'john.doe#outlook.com',
firstName: 'John',
lastName: 'Doe'
});
insertContact(db, {
email: 'jane.doe#gmail.com',
firstName: 'Jane',
lastName: 'Doe'
});
};
// create the Contacts object store and indexes
request.onupgradeneeded = (event) => {
let db = event.target.result;
//create the Contacts object store
//with auto-increment id
let store = db.createObjectStore('Contacts', {
autoIncrement: true
});
//create an index on the email property
let index = store.createIndex('email', 'email', {
unique: true
});
};
function insertContact(db, contact) {
//create a new transaction
const txn = db.transaction('Contacts','readwrite');
}
//get the Contacts object store
const store = txn.objectStore('Contacts');
let query = store.put(contact);
//handle success case
query.onsuccess = function (event) {
console.log(event);
};
//handle the error case
query.onerror = function (event) {
console.log(event.target.errorCode);
}
//close the database once the transaction completes
txn.oncomplete = function () {
db.close();
};
</script>
</body>
</html>
However, I encountered the following 2 errors which I have spent a lot of time to understand why.
Uncaught ReferenceError: txn is not defined
at indexedStorage.html:53:47
Uncaught ReferenceError: db is not defined
at request.onsuccess (indexedStorage.html:18:47)
Any help would be much appreciated.
I am following the example from the Javascript tutorial and were expected to insert the two records into the indexedDB.
You have two problems:
You placed the } ending the insertContact function too early. It needs to wrap the logic for inserting the contact
You close the database connection as soon as one transaction is done. This will make the second transaction fail - maybe not in this sample (because both transactions will be kicked off simultaneously) but it'll be a surprise if you ever do anything else with the code.
function insertContact(db, contact) {
//create a new transaction
const txn = db.transaction('Contacts','readwrite');
// Moved the } from here...
//get the Contacts object store
const store = txn.objectStore('Contacts');
let query = store.put(contact);
//handle success case
query.onsuccess = function (event) {
console.log(event);
};
//handle the error case
query.onerror = function (event) {
console.log(event.target.errorCode);
}
//close the database once the transaction completes
txn.oncomplete = function () {
// You probably don't want to do this:
// db.close();
};
} // ...to here

why is not working properly async.each nodejs?

I'm trying to use async.each function to get an array with my results from two queries. After that, I need to render this results in a web page.
The async.each function calcule the variable results properly, but, I am not be able to export this variable outside the function and render it and I don't understand why.
Here I attached the code, where I tested it. I realized that when I call "callback1" the function(error) is not working and I don't get the variable list in the console (so I won't be able to render it later on). Please I would be grateful if someone could help me with that. Thanks a lot.
var list = [];
async.each(data,
function(elem, callback1){
var classgene = '';
var custom_gene = {};
custom_gene = {Name_Gene: elem['Name_Gene']};
if (elem['Type_Gene'] == "reference") {
async.waterfall([
function(callback2){
var id = elem['Id_Genes'];
geneModel.getGenesRefClass(id, function(error, data2){
classgene = data2[0]['Class_Name'];
custom_gene['classgene'] = classgene;
callback2(custom_gene);
});
},
], function(custom_gene, err){
list.push(custom_gene);
console.log(list);
callback1();
});
}
}, function(err){
// if any of the saves produced an error, err would equal that error
if(err){
console.log(list);
}else{
console.log(list);
}
});
Your code has a few problems:
It's not calling callback2() properly. It should be callback2(null, custom_gene) (the first argument is reserved for errors, or null if there aren't any). Preferably, you should also check for error being returned by geneModel.getGenesRefClass();
The previous issue also means that you need to swap the argument of function(custom_gene, err) (it should become function(err, custom_gene));
When elem['Type_Gene'] does not equal "reference", you should still call callback1(), otherwise async.each() doesn't know that the code is done;
So the code would become something like this:
var list = [];
async.each(data, function(elem, callback1) {
var classgene = '';
var custom_gene = { Name_Gene : elem['Name_Gene'] };
if (elem['Type_Gene'] == "reference") {
async.waterfall([
function(callback2) {
var id = elem['Id_Genes'];
geneModel.getGenesRefClass(id, function(error, data2){
if (error) return callback2(error);
classgene = data2[0]['Class_Name'];
custom_gene['classgene'] = classgene;
callback2(null, custom_gene);
});
},
], function(err, custom_gene) {
// If you want to propagate errors, uncomment the following:
// if (err) return callback1(err);
list.push(custom_gene);
console.log(list);
callback1();
});
} else {
callback1();
}
}, function(err){
// if any of the saves produced an error, err would equal that error
if (err) {
console.log('An error occurred!', err);
}
console.log(list);
});

Parse Cloud Code: Logic Branching in Promises

I'm trying to write a Parse.com Cloud Code function to accomplish the following workflow:
User submits a value.
Cloud code function checks to see if that value matches any objects of type code.
If not, the function returns a "not found" value.
If so, the object of type code is assumed to have a pointer to an object of type item.
Then, code.item is checked to see whether it has a pointer to an object of type alert.
If not, the function returns a "not found" value.
If code.item.alert does exist, then I want to fetch the full alert object, including pointers which may or may not exist, up to 2 layers deep.
As I begin writing the code for this function, I can get it working to the point of checking to see whether the code exists and, if so, whether code.item.alert also exists.
This is where the problem arises. As it currently stands, in the working version of my function, the alert item that is returned is only the class type and objectId. I understand why that is happening, and I am trying to write code to populate the object before returning it, but I am failing in that attempt.
Here's the code that is working so far (but only returning the alert object's shell):
Parse.Cloud.define("alertLookup", function (request, response) {
Parse.Cloud.useMasterKey();
var codeQuery = new Parse.Query("code");
codeQuery.equalTo("value", request.params.code);
codeQuery.include("item");
codeQuery.find().then(function (codes) {
if (codes.length === 0) {
response.success("no item");
} else {
var code = codes[0];
var item = code.get("item");
var alert = item.get("alert");
if (alert === null || alert === undefined) {
response.success("no item");
} else {
response.success(alert);
}
}
}, function (error) {
response.error(error);
});
});
Here's what I have tried that is failing with an error code of 141:
Parse.Cloud.define("alertLookup", function (request, response) {
Parse.Cloud.useMasterKey();
var codeQuery = new Parse.Query("code");
codeQuery.equalTo("value", request.params.code);
codeQuery.include("item");
codeQuery.find().then(function (codes) {
if (codes.length === 0) {
response.success("no item");
} else {
var code = codes[0];
var item = code.get("item");
var alert = item.get("alert");
if (alert === null || alert === undefined) {
response.success("no item");
} else {
return alert.fetch();
}
}
}).then(function (a) {
response.success(a);
}, function (error) {
response.error(error);
});
});
Why won't the fetch() call work properly? When I insert console.log() statements, although alert is non-null, return alert.fetch(); does not ever seem to be called. At least, the response.success(a); line is never called. Why not?
Try this instead while chaining Promises:
codeQuery.find().then(function (codes) {
if (codes.length != 0) {
var code = codes[0];
var item = code.get("item");
var alert = item.get("alert");
if (alert != null && alert != undefined) {
var alertObj = new Parse.Object("alert"); // alert class ???
alertObj.id = alert.id;
return alertObj.fetch();
}
}
// return a Promise for no items
return Parse.Promise.as("no item");
}).then(function (a) {
response.success(a);
}, function (error) {
response.error(error);
});

Not able to save a custom class object in Parse

I am trying to create a Customer class object which has a one to one relation with the User class. But the object doesn't save without giving any error.
Here is my code:
Parse.Cloud.afterSave(Parse.User, function(request) {
user = request.object;
role_name = user.get("role_name");
user_name = user.get("user_name");
user_id = user.get("objectId");
if (role_name == "customer"){
user = request.object;
console.log(" I am inside if else");
var Customer = Parse.Object.extend("Customer");
var cus = new Customer();
cus.set("name2" , "albert")
var relation = cus.relation("userId");
relation.add(user);
cus.save(); // Customer object should get saved here
cus.save(null, {
success: function(cus) {
// Execute any logic that should take place after the object is saved.
console.log("I am working")
alert('New object created with objectId: ' + cus.objectId);
},
error: function(error) {
// handleParseError(error);
console.log(error)
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and message.
}
});
}
});
Log when I run this:
after_save triggered for _User for user qu808uKOgt:
Input: {"object":{"createdAt":"2015-10-11T18:36:07.661Z","objectId":"qu808uKOgt","phone":"5678956475","role_name":"customer","updatedAt":"2015-10-11T18:36:07.661Z","username":"newuser16"}}
Result: Success
I am inside if else
{"name2":"apple","userId":{"__op":"AddRelation","objects": [{"__type":"Pointer","className":"_User","objectId":"qu808uKOgt"}]}}
I fixed this bug by creating a new cloud function, which will be called immediately after the user sign's up.
Parse.Cloud.define('functionName', function(request, response){
var currentUser = Parse.User.current();
var role_name = currentUser.get("role_name");
if (role_name == "customer"){
// Do something
}
else if (role_name == "service_provider"){
// Do something else
}
)};

Exception in async function: Only on server, not on localhost

I am trying to get a route working that will function as a "Thank You" page for people who buy our products on an external store. On localhost everything works fine but on our staging server I get the following exception:
Exception in callback of async function: action#http://taskwunderstaging-45398.onmodulus.net/12289f8cf999b67e6c6c6dcad1a5a5eded53f4e2.js:517:468
Does anyone have an idea what might be causing this?
The code in question is as follows:
The Iron Router Endpoint
Router.route('/signup-partner', {
name: 'signupPartner',
where: 'client',
waitOn: function(){
return Meteor.subscribe("packages");
},
action: function() {
Meteor.logout(function() {});
var query = this.params.query;
//#TODO verify the query with the sha key!
var userInfo = {
email:query.email,
firstname:query.firstname,
lastname:query.lastname,
};
var companyInfo = {
companyName:query.company,
street:query.street,
city:query.city,
zipcode:query.zipcode,
country:query.country,
taxId:query.taxid
};
var orderInfo = {
product:query.product,
order:query.order,
};
// get the package from the database
orderInfo.package = Packages.findOne({digistoreId:orderInfo.product}).name;
orderInfo.tw_id = Packages.findOne({digistoreId:orderInfo.product})._id;
var data = {
userInfo:userInfo,
companyInfo:companyInfo,
orderInfo:orderInfo,
};
var that = this;
// check if the user account already exists and if so add the package and login the user
Meteor.call("partnerUserExists", data.userInfo.email,{orderId:data.orderInfo.order,tw_id:data.orderInfo.tw_id}, function(error, result){
if(result === "not-found"){
that.render('signup_partner',{
data: function(){
return data;
}
});
}
else {
Session.set('boughtPackage',result);
that.redirect('login');
}
});
}
});
the method that this route calls is as follows:
partnerUserExists: function(email,orderIds){
var user = Meteor.users.findOne({"emails.address":email}) || false;
console.log(user);
if(!user){
return "not-found";
}
if(_.indexOf(user.data.digistoreOrders,orderIds.orderId) > -1){
return orderIds.tw_id;
}
(function(callback){
// add the paidTask array if it doesnt exist
if (!user.data.paidTasks){
Meteor.users.update({_id:user._id},{$set:{"data.paidTasks":[]}});
}
// add the digistore array if it doesnt exist
if (!user.data.digistoreOrders){
Meteor.users.update({_id:user._id},{$set:{"data.digistoreOrders":[]}});
}
callback();
})(function(){
Meteor.users.update({_id:user._id},{$push:{"data.digistoreOrders":orderIds.orderId}});
Meteor.users.update({_id:user._id},{$push:{"data.paidTasks":orderIds.tw_id}});
return orderIds.tw_id;
});
}
check for error in your meteor.call. It should tell you if there is an error and why. If not, then try putting a console.log before each return. Overall, I see a lot of user.xx fields being accessed without checking whether that field is set. It could be one of those.

Categories