Reputation: 63
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
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
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