Help with updating service

Hi,

I am trying to subscribe/fetch updating data from a nats server and to build a realtime API for my frontend app.

I’ve been struggling with ExpressJs for a while and I started to try Resgate today.

I followed the Helloworld example and wrote the following code:

nc.subscribe('pkt', function(msg){ // subscribe updating pkt data
    console.log(msg.length, msg); // check if empty

    if(msg.length>0){ // serve data
        nc.subscribe('get.pkt', (req, reply) => {
            nc.publish(reply, JSON.stringify({ result: { model: JSON.parse(msg)}}));
        });
        
        nc.subscribe('access.pkt', (req, reply) => {
            nc.publish(reply, JSON.stringify({ result: { get: true }}));
        });
    }

})

In my console, I can see the msg gets updated frequently but the API (http://localhost:8080/api/pkt) only returns the first msg subscribed.

I am not too sure how to fix this issue.

Any help would be greatly appreciated:)

Hi, and welcome to the forum! :partying_face:

Hopefully you haven’t given up yet, even if this response is a few days late.

Are you trying to:

  1. Send a stream of messages to the client, like a chat?
  2. Have a single message that the client can fetch, and that may be updated at any time?

To achieve 2), you can start with the Edit text example. That one is a simple example of updating a message in real time.

To achieve 1), you have the options of creating a collection (list) of messages. Or you can use custom events where you simply just send messages that are not persisted, but will arrive at any subscribing client.

Which one are you aiming for?

Best regards,
Samuel

Hi,

Thanks for the reply.

There is a NATS server that publishes data every 1 minute on a specific channel.

I need to subscribe the channel to fetch and parse data and build an API for my frontend app.

I am guessing it’s the second case.

Could you tell me why the code below does not work?

nc.subscribe('pkt', function(msg){ // listen on 'pkt' channel and fetch msg data
    console.log(msg.length, msg); //  here, the msg data changes every 1 minute

    if(msg.length>0){ // but here, the msg is always the first data fetched
        nc.subscribe('get.pkt', (req, reply) => {
            nc.publish(reply, JSON.stringify({ result: { model: JSON.parse(msg)}}));
        });
        
        nc.subscribe('access.pkt', (req, reply) => {
            nc.publish(reply, JSON.stringify({ result: { get: true }}));
        });
    }

})

I am still new to Resgate and I will try to understand the Edit text example:)

Regards
Paul

One main issue of your code is that you create a new subscription to get.pkt and access.pkt every time a message is received on the pkt channel.

Then I don’t know the structure of the msg message. But let me assume it is just some ordinary flat object like (because if it is a nested object, there are some other things needed):

{ "message": "This is the message text" }

In this case, your code could look like this:

// In lastMsg we store the last message we received.
// Initially we have just an empty message.
let lastMsg = { "message": "" };

nc.subscribe('pkt', function(msg){ // listen on 'pkt' channel and fetch msg data
    console.log(msg.length, msg); //  here, the msg data changes every 1 minute

    // We only update the message if it is not empty.
    if(msg.length>0) {
        let newMsg = JSON.parse(msg);
        // We send an event to tell all subscribing clients the message has changed.
        // We could compare the new msg with the last one, to determine which
        // values has actually changed.
        // But we can also send the entire model (like below), and let Resgate
        // compare for any differences.
        nc.publish('event.pkt.change', JSON.stringify({ values: newMsg }));
        // We store away the message for the get.pkt handler.
        lastMsg = newMsg;
    }
});

// The get.pkt will respond with the last message received.
nc.subscribe('get.pkt', (req, reply) => {
    nc.publish(reply, JSON.stringify({ result: { model: lastMsg }}));
});

nc.subscribe('access.pkt', (req, reply) => {
    nc.publish(reply, JSON.stringify({ result: { get: true }}));
});

That should do it :slight_smile:

(The code is untested, but I hope I didn’t do any silly mistakes)

/Samuel

1 Like

It’s working!

Thank you so much :grin: