Sync Meteor.publish() with callback function


#1

I’m Using Meteor.publish() on the server side to fetch data from the Mysql Database Table using the numtel mysql package.

But somehow I’m unable to sync the calls on the client side.

client/templates/main.js
var selectedData = new MysqlSubscription('selectData');
calculateData(selectedData);

//perform some calculations with the above retrieved data
function calculateData(dataset) {
//calculations logic.......
}

server/dbConnection.js
var liveDb = new LiveMysql({ host: 'localhost', post: 3306, user: 'root', password: 'root', database: 'development_data' });

Meteor.publish('selectData', function() {
     return liveDb.select('select * from data_table', [{
            table: "data_table"
        }]);
    });`

Since there is no callback for the above publish function I’m unable to sync it on the client side.
As the retrieval of the data from the db takes time the calculateData() function is executed with the empty data and throws an error.

I’ve also used the above select statement within the Meteor.methods() as it supports callback function but it’s failing to execute with the Select statement while it works fine with the Insert , Update & Delete.

Please help…


#2

I would try something like:

Template.myTemplate.onCreated(function () {
  let self = this;
  self.autorun(function () {
    let selectDataSub = self.subscribe('selectData');
    if (selectDataSub.ready()) {
      calculateData(selectDataSub);
    }
  });
});

#3

It’s been a while since I used the numtel:mysql package, but the MysqlSubscription returns an object which allows you to reactively respond to the results of the query. In other words, you do not get a callback. Instead you need to use the reactive method within a reactive context (like a template helper) to get the data (this could be an autorun if you need the data in something other than a helper).

So, outside of a template, something like:

import { Tracker } from 'meteor/tracker';

const selectedData = new MysqlSubscription('selectData');

Tracker.autorun(() => {
  calculateData(selectedData.reactive());
});

function calculateData(dataset) {
  // calculations logic.......
}

However, you should be aware that the autorun will rerun whenever the result set changes (including from its initial, undefined state), so your calculateData function needs to be able to cope with this.