Waiting for change in one document

Hello,

I have an application that basically works in the following way:

  • a client sends a request to the server
  • the server communicates via MQTT to some device
  • the device answer asynchronously
  • the server stores the message from the device into a database, and put some flag to true
  • the server sends this message back to the client when the flag attribute is true

My question is how to know when the flag on a given document has just been set to ‘true’. For example let’s say my collection is called Devices. I basically want to know how to fire an event on the server whenever the device with a given _id has its attribute ‘flag’ that has just been set to ‘true’. I looked at the collection-hooks package, but I am not sure how to realise this function with this package. Any help would be appreciated. Thanks!

https://docs.meteor.com/api/collections.html#Mongo-Cursor-observe (and observeChanges) will allow you take an action on a change in the data. So there you can detect your flag.

In this specific scenario you don’t even need that specifically, this is what you can do with subscriptions :

  • a client sends a request to the server
    -> Method call(‘getDeviceStatus’, {deviceId})
    -> Client subscribes: Meteor.subscribe(‘device’, {deviceId})

  • the server communicates via MQTT to some device
    -> Custom implementation

  • the device answer asynchronously
    -> Likely with some MQTT API also? This is the event which happens on the server. You could try to detect changes in the database but here you already have an event here. So if you would like to trigger some action here is the place. You could call: Meteor.call(‘flagTurnedTrueForDevice’, {deviceId}) and handle your code further without issues.

  • the server stores the message from the device into a database, and put some flag to true
    -> Just an update query

  • the server sends this message back to the client when the flag attribute is true
    -> In this case the minimongo database on the client will update instantly. So you can have something like: if(device.flag === true) { show something }.

That will allow you to do this all reactively without custom things.

Now the nice thing about that observeChanges (see link above) is that you could also do this on the client. That’s when it becomes neat:

      var query = Devices.find();
      query.observeChanges({
        changed: function(id, fields) {
          if(fields.flag) { // check format in docs, untested
            console.log('Flag became true for: ' + id);
          }
        },
      });
      return query;
    }

That will allow you to show popups, trigger custom code etc.

Summarize

On the server you already have an event, the call from the device. So there is no direct need for a structure in between.

The client updates just reactively. That is enough for showing the flag in your templates for example.

If you need to take action in your code based on the change you can use observeChanges on the client to trigger that code easily.

Thanks a lot for the detailed answer, it worked!

1 Like