LumaPictures / meteor-jquery-datatables

Sort, page, and filter millions of records reactively.
http://jquery-datatables.meteor.com
MIT License
98 stars 29 forks source link

All the data from the collection are subscribed in other pages too #33

Open guilhermedecampo opened 10 years ago

guilhermedecampo commented 10 years ago

Hi @austinrivas thanks for this awesome package! A great contribution to the meteor environment.

I'm been using with success, but after configuring 3 datatables I notice that all the data from the DataTableComponent are subscribed to all pages.

Notice some patterns: -All the data is subscribed in the DataTable pages. ( saw via find().fetch() in browser console ) -if I change something in the same collection added to DataTable in another page the data are subscribed in this another page.

Server side

CustomersTable = new DataTableComponent({
  subscription: "customers_table",
  collection: Meteor.users
});
CustomersTable.publish();

Client side

Template.AdminCustomers.customers = function() {
  return {
    columns: [
      {
        title: "ID",
        data: "_id"
      },
      {
        title: "Creation Date",
        data: null,
        mRender: function(data, type, row) {
          if (row.createdAt === undefined) {
            row.createdAt = "";
          }
          if (row.createdAt) {
            return moment(row.createdAt).format('DD/MM/YYYY');
          } else {
            return row.createdAt;
          }
        }
      },
      {
        title: "Email",
        data: null,
        mRender: function(data, type, row) {
          if (row.emails[0].address === undefined) {
            row.emails[0].address = "";
          }
          return row.emails[0].address;
        }
      },
      {
        title: "First Name",
        data:null,
        mRender: function(data, type, row) {
          if (row.profile.firstName === undefined) {
            row.profile.firstName = "";
          }
          return row.profile.firstName;
        }
      },
      {
        title: "Last Name",
        data: null,
        mRender: function(data, type, row) {
          if (row.profile.lastName === undefined) {
            row.profile.lastName = "";
          }
          return row.profile.lastName;
        }
      },
    ],
    subscription: "customers_table"
  };
};
{{> DataTable
   columns=customers.columns
   options=customers.options
   subscription=customers.subscription
}}

Where do you think I can look to fix this problem?

Thanks man!!

guilhermedecampo commented 10 years ago

Hey @austinrivas I did a small reproduction: here

gjolund commented 10 years ago

Hi @guilhermedecampo

Thanks for the kind words, I'm happy to hear that you are finding this package useful.

To answer you question, there is a query parameter that you can define on the client and server that will allow you to limit the data set for each table.

On the server :

RowsTable = new DataTableComponent
    subscription: "rows"
    collection: Rows
    # ##### Only return the rows created today
    query:
      createdAt: $gte: moment().startOf( "day").toDate()

  RowsTable.publish()

Or if you need access the the publication context ( to check the userId for example ) use a function for the query property.

RowsTable = new DataTableComponent
    subscription: "rows"
    collection: Rows
    debug: "userId"

    # ##### Only return rows this user owns
    query: ( component ) ->
        component.log "userId", this.userId
        return { owner: this.userId }

  RowsTable.publish()

You can also define a query on the client, which will let you limit the subscription even further.

This way you can have a general subscription that publishes data for several tables, and then the tables can limit the data further for their needs.

Let me know if you need additional clarification or if anything doesn't work as expected.

guilhermedecampo commented 10 years ago

Hi @austinrivas, thanks for the prompt answer!

Sorry I didn't get it how restrict the query will help to not allow the subscription be in other pages the documents are availables. Did you see the example?

One more thing that I think is key for this problem is how come the documents don't appear in your examples(with Rows.find().fetch() in the browser console) and in my example(Order.find().fetch()) they appear?

Thanks again =)

gjolund commented 10 years ago

@guilhermedecampo each DataTable creates its own client only collection to store its data, this is to prevent tables that view the same server collection from bleeding into each other. This data is also added to the parent collection ( Rows or Order for example ) for external manipulation. The example app that is being served does not do this because it is an older version, that is why you can see the docs in your log but not on the example site.

I'm not sure I follow this "-if I change something in the same collection added to DataTable in another page the data are subscribed in this another page."

Would you mind putting together a small example app showcasing the issue?

Something that may help understand the internals a little better is to set the debug option of you components to "all"

{{> DataTable
   columns=customers.columns
   options=customers.options
   subscription=customers.subscription
   debug="all"
}}
CustomersTable = new DataTableComponent({
  subscription: "customers_table",
  collection: Meteor.users
  debug: "all"
});
CustomersTable.publish();

Then watch for logs in your console.

To limit what you are logging just change the debug value to some string found in the message you want to monitor, "collection" may be useful for example.

guilhermedecampo commented 10 years ago

@austinrivas seems that when the component DataTableComponent is destroyed the setSubscriptionAutorun is not called to stop the subscription.

http://error-jquery-datatable.meteor.com/ see the logs in the browser console.

How can I fix this?

gjolund commented 10 years ago

This is an internal bug, I'll push a fix

In the meantime try

Template.DataTable.destroyed -> @suscriptionAutorun().stop() if @subscriptionAutorun and @subscriptionAutorun().stop
gjolund commented 10 years ago

Also I was able to replicate the bug you describe earlier and will be pushing a fix along with several others in the next day or so.

guilhermedecampo commented 10 years ago

Thanks again for this man.

Awesome package ;)

guilhermedecampo commented 10 years ago

This didn't work I'll wait for the push ;)