I am sending an email upon form input from a client. This is how I handle the input on the client side:
"submit .class-name": function(event) {
var text = event.target.text.value;
Meteor.call('sendEmail', text);
}
This is how I set up email and handle the function call on the server side:
Meteor.startup(function(){
process.env.MAIL_URL="smtp://email%40gmail.com:password#smtp.gmail.com:465/";
});
Meteor.methods({
sendEmail: function(text) {
Email.send({
from: "meteor.email.2014#gmail.com",
to: "email#gmail.com",
subject: "Meteor Can Send Emails via Gmail",
text: "asdf"//placeholder for now
});
}
});
EDIT: The issue was with the html form name.
Have you confirmed that your method is being called? Try adding a console.log('test') call to your method and see if it gets printed out in your meteor bash window when you call the method.
Related
I try to send the mail using Meteor with Email package but mail not received
In client side i used this code
Meteor.call('sendEmail', 'xxx#sss.com', 'aaa#aat.com','Hello from Meteor!', 'This is a test of Email.send.');
In server side
Meteor.methods ({
sendEmail(to, from, subject, text) {
this.unblock();
Email.send({ to, from, subject, text });
}
});
In smptp.js
Meteor.startup(function () {
process.env.MAIL_URL = 'smtp://XXXXXXX:6-2KklMXNG4prgdgdfgdgdfgo46ryaMCg#smtp.mandrillapp.com:587';
});
You can't set environment variables like that. You need to put it in your settings file, ie
{
"env": {
"MAIL_URL": "smtp://XXXXXXX:6-2KklMXNG4prgdgdfgdgdfgo46ryaMCg#smtp.mandrillapp.com:587"
}
}
and then when you run meteor
meteor --settings settings.json
I am building a chat and based on the chatroom selected by the currentUser, I want to publish messages with this function:
Meteor.publish('messages',function(){
return Messages.find(
{chatId: 'QMMjBgCvLcnLvJPvx'},
sort:{timestamp: -1}
});
});
Now the chatId is still hardcoded, but it needs to be dynamic. The chatId is passed in the URL(e.g..../chat/QMMjBgCvLcnLvJPvx). In the client based code I have used to read the chatId:
var chatId = Router.current().params._id;
Iron Router
But this doesn't work server side. Is there a way to send the chatId from the URL to the server so I use Meteor.publish as mentioned above. Any help appreciated :)
Pass in the variable when you subscribe I.e.
Meteor.subscribe("messages", {chatId: Session.get("current-room")})
In the publication:
Meteor.publish('messages',function(chatId){
return Messages.find(
{chatId: chatId},
sort:{timestamp: -1}
});
});
In your route, you can subscribe to a publication and pass a param inside waitOn which will cause the app to show your loading template until the subscription is ready and the chatId will be reactive.
Configure loading template:
Router.configure({
layoutTemplate:'templateName',
loadingTemplate: 'anotherTemplateName'
});
Your route:
Router.route('/chat/:_id',{
waitOn: function(){
return Meteor.subscribe('messages', this.params._id);
},
action: function(){
//render your template with data
this.render('templateName', {
data: function () {
//will return object to the template which you can use in both HTML and JS. Also necessary for the link.
return Somethings.findOne({_id: this.params._id})
}
})
}
});
Publication:
Meteor.publish("messages", function (chatId) {
//the chatId comes from our subscribe in our route
return Messages.find({chatId: chatId});
});
Thanks for your answers and the hints. After some more modifications I arrived at this, which solved the issue:
var chatId = Router.current().params._id
this.wait(Meteor.subscribe('messages', chatId));
I want to show to the user a message like: "I have sent a email to activate your account".
I cannot because when the user has been created I have not found a hook for this.
Do you know some way to do this?
I currently show a message permanently, but I don't want this way. I just want to show once when user is singed up.
Well there are 2 options here, if you are creating the user on the client side, just use
Accounts.createUser({email: email, password: password}, function(err) {
if(!err){
alert(""I have sent a email to activate your account")
}
});
Or if you are creating the user from a method, it should look like this.
//Server.js
Meter.method({
createUser:function(username,email,password){
//create user logic.
}
})
And on the client it should look like this.
Meteor.call('createUser',username,email,password,function(err,result){
if(!err){
alert(""I have sent a email to activate your account")
}
});
On both cases we are using an extra parameter, named callback this function, accept 2 other parameters wich are err,result, so if there is not error when the accounts its created, the alert should be triggered
You should be able to add the alert in the callback from createUser() on the client. Assuming you have something like a form that you submit to create the user, then you would do ...
Template.myTemplate.events({
'submit #new-user-form': function(event) {
// These next few lines will depend on what your template looks like and what data you require on login
// Here I've assumed just username and pw in appropriately-named inputs on your page
var email = $('#email-input').val();
var password = $('#password-input').val();
event.preventDefault();
Accounts.createUser({email: email, password: password}, function(error) {
if (error) { alert("There was an error!"); }
else { alert("I have sent you an email to verify your account"); }
});
}
});
If you want to accomplish this behavior with accounts-ui installed, the documentation doesn't show anything you can hook into. However, you can do it manually like so:
Template.myTemplate.events({
'click .login-form-create-account #login-buttons-password': function() {
alert("I sent you an email to verify your account");
}
});
Unfortunately, that will still fire even if the user was not successfully created.
I'm writing an Appliction using Meteor. In this App I want to implement a server-side validation of the user data using Accounts.onCreateUser. There is some data passed which can only be verified on the server side.
At client side I call:
Template.register.events({
'submit form': function (e) {
e.preventDefault();
var attributes = {
username: $("#inputUsername").val(),
password: $("#inputPassword").val(),
confirmation: $("inputConfirmation").val(),
email: $("#inputEmail").val(),
...
};
Accounts.createUser(attributes, function(err){
if (err) {
throwError(err);
} else {
}
});
}
});
And on the server side:
Accounts.onCreateUser(function(options, user) {
if(!verifyData(options))
throw new Meteor.Error(403, "Wrong input");
return user;
});
After the server side verification fails, all form data is lost. What is the best way to keep the data?
I went ahead and reproduced your code on a Meteorpad and from what I can tell, the form data does still persist. You just need to access it via the attributes variable in the client-side.
There may be something I am missing, but i took what you posted above and put it in there.
I'm trying to see how can I invoke a js function after the client gets a result from a Meteor method call. The only thing I was able to get is to invoke the function myFunc only on the client that made the actual method call.
Any thoughts how i can invoke the function on all the currently subscribed clients?
here is the code:
function myFunc(error, result) {
alert(result);
}
if (Meteor.is_client) {
Template.container.events = {
'click input' : function () {
Meteor.call('someMethod',myFunc);
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
};
}
if (Meteor.is_server) {
Meteor.startup(function () {
// code to run on server at startup
});
}
Meteor.methods({
someMethod: function() {
//console.log(!this.is_simulation);
return "something";
}
})
Thanks
Currently you can't broadcast a method call to all clients directly. At least as far as I can tell. But a work around would be to create a collection called Alerts and monitor it for changes. Then when you want to send a message to all your users you can change the document in Alerts:
Client:
Alerts = new Meteor.Collection("alerts")
Meteor.autosubscribe(function() {
Alerts.find().observe({
added: function(item){
alert(item.message);
}
});
});
Server:
Alerts = new Meteor.Collection("alerts")
Meteor.publish("alerts", function(){
Alerts.find();
});
Alerts.remove({}); // remove all
Alerts.insert({message: "Some message to show on every client."});
Another option is using Meteor Stream package which purpose is to avoid using a mongodb collection on the server side. It does supports client to clients, server to clients, client to server AND server to servers messaging, including a support for Meteor Cluster
If you want to stay with meteor only using collections, the following code allows you to either broadcast a message from the client to all the clients or a message from the server to all the subscribed clients. Just use this mechanism to then fire a function on the client side once the right message is received. The code is made in such a way that you will never have useless items remaining into the collection.
Messages = new Meteor.Collection("messages");
if (Meteor.isClient) {
Meteor.subscribe("messages");
var query = Messages.find({});
var handle = query.observe({
added: function(document)
{
console.log(document.message);
}
});
// Test the mechanism from the client side
Meteor.call("client talked");
}
if (Meteor.isServer) {
Meteor.startup(function() {
Messages.remove({});
});
Meteor.publish("messages", function()
{
// you might add an optional filter in order to broadcast only the messages you want to the client
return Messages.find();
});
function talk(message)
{
var id = Messages.insert({"message":message});
Messages.remove(id);
}
Meteor.methods(
{
talk: function(message)
{
// you might filter here if the clients can talk using this.userId
talk(message);
}
});
// test the mechanism from the server side
talk("server talked");
}
I like what Zeke said, but for people who uses Meteor 0.5.0+, use Deps.autorun instead of autosubscribe... details at:
https://groups.google.com/forum/#!topic/meteor-core/mTa81RLvhbY
and
http://www.meteor.com/blog/2013/02/14/meteor-055-devshop-code-and-community-contributions
I simple approach to call a JavaScript client-side function would be to add a script tag in your html template that is bound by your collection. Anytime a new item is inserted, this tag would be inserted into the client would run your function. I have a collection call uploads with some properties such as name. The following template triggers drawpoints() client-side function upon receipt of a new item in Uploads collection:
{{#each uploads}}
<tr>
<td>{{name}}</td>
<td>
<div class="alert alert-success">Download Here</div>
</td>
</tr>
<script>drawpoints();</script>
{{/each}}