Search code examples
node.jsrabbitmqnode-amqplib

How to extract msg from channel.consume


I was successfully consumed the message from rabbitmq, I can see the message if I add console.log(msg), but the problem is I can't get the msg outside the channel.consume

I tried to assign it to variable but it's still didn't work

const connection = await amqp.connect("amqp://localhost")
const channel = await connection.createChannel()
const queue = 'data-portal-response'

var messageString;
channel.consume(queue, msg => {
    console.log('Checking message...');
    if (msg !== null) {
        messageString = msg.content.toString();
        console.log('Acknowledging message..');
        channel.ack(msg);
        console.log('Acknowledged.');
        return messageString;
    } else {
        console.log('No messages to consume.');
        return null;
    }
});


console.log(messageString);

I'm expecting the code to print messageString outside the consume part console.log(messageString);


Solution

  • Given the following:

    channel.consume(queue, msg => { ... });
    

    Your expectation, stated below,

    I'm expecting the code to print messageString outside the consume part console.log(messageString);

    is an unfortunate expectation. The code you have above executes a callback in an arrow function with each received message. The arrow will inherit the scope from the parent context, but you cannot go the other direction. Thus, two things happen:

    1. Consume is called, and
    2. The string 'undefined' is logged to your console. That is because the next line to run is NOT inside the lambda, but is rather the console.log(messageString), which at that time is undefined.

    Instead, you need to move your console.log statement INSIDE the arrow function. If you need some other function to run in the parent scope (which I assume is what you need), then you'll have to define that as a separate function and call it from your arrow function.

    For example:

    let consumerTag = channel.consume(queue, msg => {
        console.log('Message received: ...');
        var messageString = msg.content.toString();
        this.doSomethingUsefulWith(messageString);
    
        console.log('Acknowledging message..');
        channel.ack(msg);
    });
    
    function doSomethingUsefulWith(messageString) { ... }