H. Solatges
H. Solatges

Reputation: 63

Meteor.publish() throw an exception in defer callback

I found this error in the server console:

Exception in defer callback: TypeError: undefined is not a function at packages/ddp/livedata_server.js:1054:1 at Array.forEach (native) at Function..each..forEach (packages/underscore/underscore.js:105:1) at [object Object]._.extend._callStopCallbacks (packages/ddp/livedata_server.js:1053:1) at [object Object]._.extend._deactivate (packages/ddp/livedata_server.js:1043:1) at packages/ddp/livedata_server.js:803:1 at Function..each..forEach (packages/underscore/underscore.js:113:1) at [object Object]._.extend._deactivateAllSubscriptions (packages/ddp/livedata_server.js:802:1) at packages/ddp/livedata_server.js:444:1 at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)

And here the code I use:

/* Source: http://phucnguyen.info/blog/how-to-publish-to-a-client-only-collection-in-meteor/ */
var subs = {};
Meteor.publish(

// THROW AN 'EXCEPTION IN DERFER CALLBACK: ...'
  'helperPublication',  
  function () {
    var subscription = this;
    subs[subscription._session.id] = subscription;
    Datasets.find().map(function (dataset) {
      subscription.added(
        'subdatasets',
        dataset._id,
        {
          name: dataset.name,
          data: [],   // To avoid "Uncaught TypeError: Cannot read property 'length' of undefined" error on load
          peaks: []   // Idem
        }
      )
    });
    subscription.onStop();
    subscription.ready()
});

You can find the whole app in the following meteorpad: http://meteorpad.com/pad/6NDneym2qEW7pF9JM/ClearChrom

Upvotes: 0

Views: 1184

Answers (2)

Aniket Teltumbade
Aniket Teltumbade

Reputation: 1

I solved this with different approach. There is a Method inside Meteor docs. (Check here in doc Meteor.bindEnvironment)

          const _this = this;

          Meteor.defer(Meteor.bindEnvironment(() => {

              // Your Code here

          }, 
          (exception/error) => { 
              // exception/error throw
          }, 
          _this));

I think somehow it looses context with this inside Meteor.defer. And Above code provides that context. This way I resolved my issue

Upvotes: 0

halbgut
halbgut

Reputation: 2386

Ok, So with that info; I think the best way to go about doing this is to have separate collection for that data. Because then you can easily change how much data should be displayed. The publication for that collection could look like this:

Meteor.publish('data', function publishData (limit) {
  return DataCollection.find({}, {
    fields: {
      name: 1,
      data: 1,
      peaks: 1
    },
    limit: limit
  })
});

Note that the callback of the publication takes an argument limit. You can now subscribe to it like this:

Meteor.subscribe('data', 3)

And whenever you need more data you can just:

Meteor.subscribe('data', 6)

So this solution is reactive and very clean (in my opinion at least).

I also checked your existing script:

var subs = {};

Meteor.publish(
  'helperPublication',
  function (limit) {
    var subscription = this;
    subs[subscription._session.id] = subscription;
    // I'd use forEach here, because you're not modifying the document
    Datasets.find().forEach(function (doc) {
      subscription.added(
        'subdatasets',
        doc._id,
        {
          name: doc.name,
          // Whith the slice function you can get a subset of the data array
          data: doc.data.slice(0, limit),
          peaks: doc.peaks
        }
      )
    });
    // Calling `subscription.onStop` without an argument doesn't do anything
    // Except maybe through an error
    subscription.onStop(function () {
      // clean the subscription from subs again
      delete subs[subscription._session.id];
    });
    // This shouldn't be necessary.
    // subscription.ready()
});

There are some issues with this still. For one thing I'd advise you to try avoiding meteor attributes with an underscore in front. They might be removed or changed in future releases.

Upvotes: 1

Related Questions