1

I am trying to build a small library to abstract some of the boilerplate needed with amqplib to communicate with RabbitMQ. I am using the promises api and the async/await syntax. I am trying to build a class with some methods to use with several other servers and clients. I have searched online and the vast majority of the examples are direct, small scale tutorials.

Here is what I have so far for messages.js:

const amqp = require('amqplib');

module.exports = class MQ {
    constructor(user, password, host, port) {
        this.conn;
        this.uri = 'amqp://' + user + ':' + password + '@' + host + ':' + port;
        this.channel;
        this.q = '';
    }
    async setupConnection() {
        this.conn = await amqp.connect(this.uri);
        this.channel = await this.conn.createChannel();

        await this.channel.assertQueue(this.q, { durable: false });
    }   

    send(msg) {
        this.channel.sendToQueue(this.q, Buffer.from(msg));
        console.log(' [x] Sent %s', msg);
    }

    async recv() {
        await this.channel.consume(this.q), (msg) =>{
            const result = msg.content.toString();
            console.log(`Receive ${result}`);
        };
    }
}

Here is the code for setup.js:

const MQ = require('./message');

msgq = new MQ('guest', 'guest', 'localhost', '5672')

msgq.setupConnection();

msgq.send('Test this message');

The error I get when I try to send the message is "TypeError: Cannot read property 'sendToQueue' of undefined." Apparently the channel property is not being initialized properly. I enclosed the async/awaits in try/catch blocks and get the same error.

Is there something I am missing about classes/methods in Node.js?

I think this has something to do with the resolution of the promises. When I move the call to sendToQueue() up to the setupConnection() method, the message gets sent.

So it seems that I need to find a way to have the send method wait on the resolution of the setup method.

Paul D.
  • 591
  • 7
  • 17

1 Answers1

1

You are not running your code asynchronously, so send is getting called before a connection has been established. You need to chain the promises to be guaranteed that the connection function has completed before trying to send. Try this:

const MQ = require('./message');

msgq = new MQ('guest', 'guest', 'localhost', '5672')

msgq.setupConnection()
.then(() => {
    msgq.send('Test this message');
})
Richard Dunn
  • 6,165
  • 1
  • 25
  • 36