I'm currently working on a project to make a Pinterest clone in Meteor. The users need to fill in three test when they create an account, so I need to make a custom registration/login system. For now, I can create a new account, but when I want to log in with Meteor.loginWithPassword() nothing happens. Even no error or result.
Here's my code:
'submit .login-form': function(event){
event.preventDefault();
var emailVar = event.target.loginEmail.value;
var passwordVar = event.target.loginPassword.value;
console.log('here') // This is shown in the console
console.log(Meteor.loginWithPassword()) // gives undefined
Meteor.loginWithPassword(emailVar, passwordVar, function(err, suc) {
if (err) {
console.log(err); // This isn't shown in the console
} else {
console.log(succ); // This isn't shown in the console
Bert.alert({
title: "Welkom: " + Meteor.user().profile.name,
message: 'You're logged in!',
type: 'success',
style: 'growl-top-right',
icon: 'fa-check'
});
}
});
}
Edit:
As asked here's is the user in Meteor.users:
Image
And here are the strings that are filled in: Image
this should work:
'submit .login-form': function (event) {
event.preventDefault();
var emailVar = event.target.loginEmail.value;
var passwordVar = event.target.loginPassword.value;
Meteor.loginWithPassword(emailVar, passwordVar, function (err) {
if (!err) {
console.log("User logged in");
Bert.alert({
title: "Welkom: " + Meteor.user().profile.name,
message: "You're logged in !",
type: 'success',
style: 'growl-top-right',
icon: 'fa-check'
});
} else{
// Do something on error....
console.log("Not logged in, and error occurred:", err); // Outputs error
}
});
}
Related
I've got two methods on a same event click .open-message :
sendEmailContact : this method send a mail
openMessage : this method update the message (from new state to responded state)
The two methods are working fine, but separately.
My idea is to pass Meteor.call('sendEmailContact' and on success only, to pass Meteor.call('openMessage'
Below my current event & my unsuccess try
current event
Template.Users.events({
'click .open-message':function() {
Meteor.call('openMessage', this._id, function(error) {
if(error) {
Bert.alert({
title: 'Error',
message: error.reason,
type: 'danger'
});
} else {console.log ("ok");}
});
var to = this.email; // catch the to value
var contactmessage = this.message; // catch the original message
swal({
input: 'textarea',
title: "Response to " + to,
text: "H " + contactmessage,
type: "",
showCloseButton: true,
showCancelButton: true,
confirmButtonColor: "#272b35",
confirmButtonText: "Send"
}).then(function (text){
if(message != '') {
var from = "my#mail.com"
var subject = "Response to your message";
var message = text; //catch the value of the textarea
Meteor.call('sendEmailContact', to, from, subject, message, contactmessage, (error) => {
if(error) {
Bert.alert({
title: 'Error',
message: error.reason,
type: 'danger'
});
console.log (to);
console.log (from);
console.log (subject);
console.log (message);
} else {
console.log (to);
console.log (from);
console.log (subject);
console.log (message);
//target.text.value = ''; // Clear form
Bert.alert({
title: 'Success',
message: 'Message sended.',
type: 'success'
});
}
});
} else {
Bert.alert({
title: 'Error',
message: 'Message error.',
type: 'danger'
});
console.log (to);
console.log (from);
console.log (subject);
console.log (message);
}
}, function (dismiss) {
if (dismiss === 'cancel') {
null
//handle dismiss events like 'cancel', 'overlay', 'close', and 'timer'
}
})
}
});
unsuccess try (no error, the first method ok, but nothing on the second (console.log ("ok"); works))
Template.Users.events({
'click .open-message':function() {
var to = this.email; // catch the to value
var contactmessage = this.message; // catch the original message
swal({
input: 'textarea',
title: "Response to " + to,
text: "H " + contactmessage,
type: "",
showCloseButton: true,
showCancelButton: true,
confirmButtonColor: "#272b35",
confirmButtonText: "Send"
}).then(function (text){
if(message != '') {
var from = "my#mail.com"
var subject = "Response to your message";
var message = text; //catch the value of the textarea
Meteor.call('sendEmailContact', to, from, subject, message, contactmessage, (error) => {
if(error) {
Bert.alert({
title: 'Error',
message: error.reason,
type: 'danger'
});
console.log (to);
console.log (from);
console.log (subject);
console.log (message);
} else {
Meteor.call('openMessage', this._id, function(error) {
if(error) {
Bert.alert({
title: 'Error',
message: error.reason,
type: 'danger'
});
} else {console.log ("ok");}
});
console.log (to);
console.log (from);
console.log (subject);
console.log (message);
//target.text.value = ''; // Clear form
Bert.alert({
title: 'Success',
message: 'Message sended.',
type: 'success'
});
}
});
} else {
Bert.alert({
title: 'Error',
message: 'Message error.',
type: 'danger'
});
console.log (to);
console.log (from);
console.log (subject);
console.log (message);
}
}, function (dismiss) {
if (dismiss === 'cancel') {
null
//handle dismiss events like 'cancel', 'overlay', 'close', and 'timer'
}
})
}
});
EDIT
Below the two methods :
//Contact Method
Meteor.methods({
insertMessage: function(message) {
ContactMessages.insert(message);
},
openMessage: function(messageId) {
ContactMessages.update({_id: messageId}, {$set: {new: false, responded: true}});
},
deleteMessage: function(messageId) {
ContactMessages.remove({_id: messageId});
}
});
//Send ContactReply Method
Meteor.methods({
sendEmailContact: function(to, from, subject, message, contactmessage) {
check([to, from, subject, message, contactmessage], [String]);
// Let other method calls from the same client start running,
// without waiting for the email sending to complete.
this.unblock();
Email.send({
to: to,
from: from,
subject: subject,
text: message + contactmessage
});
}
});
You'll need to pass the messageId as an extra parameter to sendEmailContact from the client but then it should be pretty simple:
Meteor.methods({
insertMessage(message) {
ContactMessages.insert(message);
},
openMessage(messageId) {
ContactMessages.update(messageId, {$set: {new: false, responded: true}});
},
deleteMessage(messageId) {
ContactMessages.remove(messageId);
}
});
//Send ContactReply Method
Meteor.methods({
sendEmailContact(messageId,to, from, subject, message, contactmessage) {
check([messageId, to, from, subject, message, contactmessage], [String]);
this.unblock();
Email.send({
to: to,
from: from,
subject: subject,
text: message + contactmessage
});
Meteor.call('openMessage',messageId);
}
});
You don't even need a callback from the embedded Meteor.call() unless you want to log a potential error there.
in your 2nd example:
Meteor.call('openMessage', this._id, function(error) {
i think it doesn't know what "this" is.
so save it off at the top of the function and use the saved value through closure.
i'm also wondering why it's important that the client be the one to invoke both methods. it's technically possible to handle all that on the server; is that something that makes sense in your app?
I have a meteor project where all my users have their own profile page setup in this way using routes:
Routes code:
Router.route('/#:username', {
name: 'profile',
controller: 'ProfileController'
});
ProfileController = RouteController.extend({
template: 'profile',
waitOn: function() {
return Meteor.subscribe('userProfile', this.params.username);
},
data: function() {
var username = Router.current().params.username;
return Meteor.users.findOne({
username: username
});
}
});
Server code:
Meteor.publish('users', function() {
return Meteor.users.find({}, {fields: {username: 1, emails: 1, profile: 1, roles: 1}});
});
Meteor.publish('userProfile', function(username) {
// Try to find the user by username
var user = Meteor.users.findOne({
username: username
});
// If we can't find it, mark the subscription as ready and quit
if (!user) {
this.ready();
return;
}
// If the user we want to display the profile is the currently logged in user
if(this.userId === user._id) {
// Then we return the curresonding full document via a cursor
return Meteor.users.find(this.userId);
} else {
return Meteor.users.find(user._id, {
fields: {
profile: 0
}
});
}
});
I want to do something similar with a pages collection that I've set up. Creating the collection works and the collection page has an _id field that is made upon creation.
Right now the program works nicely for users where mysite.com/# works. Now I want the same thing to work for mysite.com/&
I've basically attempted to do the exact same thing as I did in the above code with the user name but it wasn't working. I've checked to make sure my creation of the collection items are working and they are. But somehow I can't figure out how to do this same thing with collections since I'm relatively new to using routes.
This is what I've attempted:
Here's my routes:
var pageRoute = '/&:_id';
Router.route(pageRoute, {
name: 'page',
controller: 'PageController'
});
PageController = RouteController.extend({
template: 'page',
waitOn: function() {
return Meteor.subscribe('Page', this.params._id);
},
data: function() {
var _id = Router.current().params._id;
return Meteor.pages.findOne({
_id: _id
});
}
});
Server code:
Meteor.publish('pages', function() {
return Pages.find({});
});
Meteor.publish('Page', function(_id) {
// Try find the page by _id
var page = Meteor.pages.findOne({
_id: _id
});
// If we can't find it, mark the subscription as ready and quit
if (!page) {
this.ready();
return;
}
// If the page we want to display is not claimed, display it
if(true) {
return Meteor.pages.find(this._id);
} else {
// Redirect to the page
}
});
The Schema of the Page Collection:
_id: ,
createdAt: ,
CreatedBy: ,
claimedAt: ,
claimedBy: ,
Update:
I've scoped it down to this problem, I get the following error in the console server-side:
I20160202-11:16:24.644(2)? Exception from sub qrPage id 2kY6RKCTuCpBDbuzm TypeError: Cannot call method 'findOne' of undefined
I20160202-11:16:24.645(2)? at [object Object].process.env.MAIL_URL [as _handler] (server/ecclesia.life_server.js:40:33)
I20160202-11:16:24.645(2)? at maybeAuditArgumentChecks (livedata_server.js:1698:12)
I20160202-11:16:24.645(2)? at [object Object]._.extend._runHandler (livedata_server.js:1023:17)
I20160202-11:16:24.645(2)? at [object Object]._.extend._startSubscription (livedata_server.js:842:9)
I20160202-11:16:24.646(2)? at [object Object]._.extend.protocol_handlers.sub (livedata_server.js:614:12)
I20160202-11:16:24.646(2)? at livedata_server.js:548:43
This error occurs whenever I try to direct to mysite.com/&<_id>
Based on this website: https://perishablepress.com/stop-using-unsafe-characters-in-urls/
It looks like # is considered an unsafe character to use in a URL string. On the web page above, it looks like there are several symbols you could use instead as safe characters.
I just tried this on my own machine, and I don't think Meteor plays nicely when the # is introduced in the URL.
This got it working...
Publications:
Meteor.publish('qrpages', function() {
return QRPages.find({});
});
Meteor.publish('qrPage', function(id) {
// Try find the qrpage by _id
var qrpage = QRPages.find({_id: id});
// If we can't find it, mark the subscription as ready and quit
if (!qrpage) {
this.ready();
return;
}
return qrpage;
});
Routes:
var qrpageRoute = '/$:_id';
Router.route(qrpageRoute, {
name: 'qrpage',
controller: 'QRController'
});
QRController = RouteController.extend({
template: 'qrpage',
waitOn: function() {
var id = this.params._id;
return Meteor.subscribe('qrPage', id);
},
data: function() {
var id = this.params._id;
return QRPages.findOne({
_id: id
});
}
});
I am in the process of integrating stripe payments on my website, but I have run into a problem.
I want to transition the user to a dynamic route upon submitting the payments form (iframe supplied by stripe), but the Meteor method that I call on the client returns undefined instead of the ID of the newly inserted document that I wish to transition to
Any advice?
ERROR
Error: Missing required parameters on path "/purchases/:purchaseId". The missing params are: ["purchaseId"]. The params object passed in was: undefined.
client:
Template.viewTab.events({
'click #download': function(event) {
handler.open({
name: 'Tabr',
description: this.title,
amount: this.price
});
event.preventDefault();
},
});
var handler = StripeCheckout.configure({
key: '..............',
token: function(token) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
tabId = Tabs.findOne()._id;
Meteor.call('makePurchase', tabId, token, function(error, purchaseId) {
if (error) {
console.log('makePurchaseError: ' + error);
FlashMessages.clear();
return FlashMessages.sendError(error.message, {
autoHide: true,
hideDelay: 10000
});
}
console.log(purchaseId);
Router.go('viewPurchase', purchaseId);
});
}
});
Server:
Meteor.methods({
/**
* [makePurchase attempts to charge the customer's credit card, and if succesful
* it inserts a new purchaes document in the database]
*
* #return {[String]} [purchaseId]
*/
makePurchase: function(tabId, token) {
check(tabId, String);
tab = Tabs.findOne(tabId);
Stripe.charges.create({
amount: tab.price,
currency: "USD",
card: token.id
}, Meteor.bindEnvironment(function (error, result) {
if (error) {
console.log('makePurchaseError: ' + error);
return error;
}
purchaseId = Purchases.insert({
sellerId: tab.userId,
tabId: tab._id,
price: tab.price
}, function(error, result) {
if (error) {
console.log('InsertionError: ' + error);
return error;
}
return result;
});
}));
console.log(purchaseId);
return purchaseId;
}
});
I have publish code on server-side:
Meteor.publish("getChannelsList", function() {
return News.find({ }, { title: 1 });
});
And subscriptions.js on client:
Meteor.subscribe("getChannelsList", function(err, res) {
if (err) {
throw new Meteor.Error("Subscription error", "Exception in Meteor.subscribe method", err);
}
return res;
});
Collection in it's own "collections" directory
News = new Meteor.Collection("newsStock");
This is my template helper:
Template.channel.helpers({
channels: function() {
return News.find({ }, { title: 1 });
}
});
Autopublish and insecure were removed.
I'm waiting on client database object with "title" and "id" only. If I do in browser debugger News.find().pretty() why I see whole object, with all fields? Removing autopublish is not affect for me.
Can I do multiple publications and subscribes and how it's works?
If you're only intending to return the title, it should be:
Template.channel.helpers({
channels: function() {
return News.find({ }, {
fields: {
title: 1
}
});
}
});
As you point out, this will also publish the _id by default.
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.