Using this.added

I’m trying to transform a publication, and this is my code:

Meteor.publish('appointments.waiting', function () {
    var self = this,
        count = 0;

    Appointments.find().forEach(function (appointment) {
        var patients = Patients.find({_id: appointment.patient_id}).fetch();
        var first_name = patients[count].profile.first_name,
            middle_name = patients[count].profile.middle_name,
            surname = patients[count].profile.surname,
            name = surname + ', ' + first_name + ' ' + middle_name;

        self.added('appointments', appointment.names, name);

    });

    self.ready();
});

When I console.log(name), I can see the name in full but I’m not quite sure how to use this.added to add the new data. How do I go about this? And if I do enter this new data, will it overwrite the older data?

EDIT:
If there’s a better way to achieve this, I’d also like to know.

self.added('appointments', appointment.names, {name: name});

Thanks for replying.

It works, save for one thing. It only shows the first result then exits.

Can you explain further?

Right, sorry. I was very vague. What I mean is, I’ve subscribed to the publication like so,

Template.patientRow.onCreated(function () {
  this.subscribe("appointments");
});

Template.patientRow.helpers({
   appointments: function () {
       return Appointments.find();
    }
});

And in my template, I’ve tried to use the data like this:

{{#each appointments}}
    <tr>    
      <td>{{name}}</td>
    </tr>
{{/each}}

In the collection, there’s three entries that should match, but it’s only showing the first one. So I’m only getting one row in my table.

Yeah, you need to observe the cursor for updates since .forEach isn’t reactive

...
forEach(function () {
  Appointments.find().forEach(...);
});

Appointments.find().observe({
  added: function () {
    forEach();
  },
  removed...
});

Thanks! It works! :grin:

1 Like

As much as the publish is working, I keep getting this error in the console whenever I try to update a document:

I20160828-23:46:59.384(3)? Exception in queued task: ReferenceError: transform is not defined
I20160828-23:46:59.389(3)?     at Object.changed (server/publications/appointments-publications.js:11:59)
I20160828-23:46:59.394(3)?     at [object Object].observeChangesCallbacks.changed (packages/minimongo/observe.js:162:1)
I20160828-23:46:59.397(3)?     at self.applyChange.changed (packages/minimongo/observe.js:66:1)
I20160828-23:46:59.400(3)?     at packages/mongo/observe_multiplex.js:183:30
I20160828-23:46:59.402(3)?     at Array.forEach (native)
I20160828-23:46:59.405(3)?     at Function._.each._.forEach (packages/underscore/underscore.js:105:1)
I20160828-23:46:59.408(3)?     at Object.task (packages/mongo/observe_multiplex.js:177:9)
I20160828-23:46:59.411(3)?     at [object Object]._.extend._run (packages/meteor/fiber_helpers.js:147:1)
I20160828-23:46:59.415(3)?     at packages/meteor/fiber_helpers.js:125:1

I updated my pub to look like this:

/* appointments-publications.js */
Meteor.publish('appointments.waiting', function () {
// Transforming data in a collection

  var self = this;
  var observer = Appointments.find({status: 'Waiting'}).observe({
    added: function (document) {
        self.added('appointments', document._id, transformAppointments (document));
    },
    changed: function (newDocument, oldDocument) {
        self.changed('appointments', oldDocument._id, transform(newDocument));
    },
    removed: function (oldDocument) {
        self.removed('appointments', oldDocument._id);
    }
  });

  self.onStop(function () {
    observer.stop();
  });

  self.ready();
});

And this is how I update:

/* appointments.js */
 Meteor.call('UpdateAppointment', {
   _id: appointmentId,
   patient_id: patientId,
   status: status,
   booked: booked
 }, function (error, result) {
   if (error) return console.log('Error: ' + error.error);
 });

 /* methods.js */
 Meteor.methods({
   'UpdateAppointment': function (data) {
      check(data, {
        _id: String,
        patient_id: String,
        status: String,
        booked: Boolean
      });

      return Appointments.update(data._id, {
        $set: {
            patient_id: data.patient_id,
            status: data.status,
            booked: data.booked
        }
      });
   }
});

Do you, by any chance, know what’s happening here?

From the docs: “Transforms are not applied for the callbacks of observeChanges or to cursors returned from publish functions.”

Looks like you are trying to use a global transform function