0

So, I'm trying to send an email confirmation token to an user, and for that, I'm trying to use the crypto module to generate the token. I have this:

var transport = this.NewTransport(), // This generates a nodemailer transport
    token;

// Generates the token
require('crypto').randomBytes(48, function(ex, buf) {
    token =  buf.toString('hex');
});

// Uses nodemailer to send the message, with the token.
var message = {

    from: 'test@email.com',

    to: 'receiver@email.com',

    subject: 'Token', 

    text: token,

    html: token
};

transport.sendMail(message, function(err){
    if(err) return res.send({s: 0});
    return res.send({s: 1});
});

Well, the token generated by the crypto module isn't getting assigned to the token variable, I assume this is because of the asynchronous nature of the randomBytes function.

How can I actually... save the token somewhere so I can send it through the email? Or do I have to include ALL of the email-sending code inside of the randomBytes callback function? Is this the way it has to be done in node? Is there any other way, so that the token gets generated in time, and actually sent?

Sorry, I'm quite new to node and I'm still confused about callbacks sometimes. Thanks.

JamesD
  • 3
  • 1
  • 1
    Put the message and sendmail in a function and fire off that function in the crypto callback. – bloodyKnuckles Mar 23 '15 at 00:44
  • Alright, so everything has to be pretty much inside of a callback? I'm also planning on storing the token inside of a database (which would be asynchronous too), so I would have to put callbacks within callbacks, and so on? – JamesD Mar 23 '15 at 00:47
  • Asynchronous methods only need to be nested if the outcome is needed for another method, such as your crypto. You need the token before you can send the mail. But, sending mail and putting the token in a database can be fired off together since they don't rely on each other. – bloodyKnuckles Mar 23 '15 at 00:51

1 Answers1

1

You should really wrap your code within functions. It makes it easier to manage callbacks and simultaneously maintain the code. Have a look at how I reworked what you provided... Keep in mind I haven't checked the code so there may be a few bugs.

var crypto = require('crypto'),
    transport = this.NewTransport(); // This generates a nodemailer transport

generateToken(sendMail);

function generateToken(callback) {
    // Generates the token
    var token;

    crypto.randomBytes(48, function(ex, buf) {
        token =  buf.toString('hex');

        if (typeof callback === 'function') {
            callback(token);
        }
    });
}

function sendMail(token) {
    // Uses nodemailer to send the message, with the token.
    var message = {

        from: 'test@email.com',

        to: 'receiver@email.com',

        subject: 'Token', 

        text: token,

        html: token
    };

    transport.sendMail(message, function(err){
        if(err) return res.send({s: 0});
        return res.send({s: 1});
    });
}
Jonathan
  • 62
  • 1
  • 9
  • 1
    Aaaah, I get the idea. I had never really had to do anything like this with my newly started Node.js journey, I imagine this would help a lot in situations where you need way more callbacks, so it doesn't get messy. I'll be doing it like this from now on. And the code (this code) works, by the way, thank you. – JamesD Mar 23 '15 at 01:08
  • Done that, enjoy those marvelous points! – JamesD Mar 23 '15 at 01:12