Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactivity of the table with a mongo view as collection #417

Open
ruerob opened this issue Aug 10, 2018 · 3 comments
Open

Reactivity of the table with a mongo view as collection #417

ruerob opened this issue Aug 10, 2018 · 3 comments

Comments

@ruerob
Copy link

ruerob commented Aug 10, 2018

Hej hej! :0D

I hope you can help me.

I've set up a table that has a mongo view as the collection option.
All needed collection fields are either in the columns data or in extraFields...
My selector uses one of those fields to select the visible entries. I named this field 'hidden'...

For my example lets assume I have 2 entries in my list and change the hidden value of one of those to true.

Now it needs some seconds to switch the count from "Showing 1 to 2 of 2 entries" to "Showing 1 to 1 of 1 entries"... But the hidden entry stays visible until I change the values of the selector or the route of the program...

Have I done something wrong? Is it a bad idea to use views as collections? What else could I do to get merged data from multiple collections into a single table and keep the data sortable. :0D

Thank you in advance for your help,
desperately Robert

@ruerob
Copy link
Author

ruerob commented Sep 5, 2018

I've found a solution, but I'm not sure if that was a good idea. :0D

I downloaded the source code and have put it into a package folder in my source code. That made meteor use my local code and not that from atmosphere.

Then I added one line at code line at line 119 in server/main to the updateRecords function. Now it looks like this:

  let updateRecords = () => {

    filteredRecordIds = filteredCursor.map(doc => doc._id);

    let currentCount;
    if (!table.skipCount) {
      if (typeof table.alternativeCount === 'function') {
        currentCount = table.alternativeCount(selector);
      } else {
        currentCount = countCursor.count();
      }
    }

    // From https://datatables.net/manual/server-side
    // recordsTotal: Total records, before filtering (i.e. the total number of records in the database)
    // recordsFiltered: Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned for this page of data).

    const record = {
      ids: filteredRecordIds,
      // count() will give us the updated total count
      // every time. It does not take the find options
      // limit into account.
      recordsTotal: table.skipCount ? fakeCount : currentCount,
      recordsFiltered: table.skipCount ? fakeCount : currentCount
    };

    if (recordReady) {
      //console.log('changed', tableName, record);
      this.changed('tabular_records', tableName, record);
    } else {
      //console.log('added', tableName, record);
      this.added('tabular_records', tableName, record);
      recordReady = true;
    }
  };

@aldeed Can this become a performance issue?

@ruerob
Copy link
Author

ruerob commented Sep 5, 2018

Mmmhhh... At least it solves half my problem...

If I update data that is not connected with the selector, I get no update...
But maybe I find a way to solve this problem, too...

@ruerob
Copy link
Author

ruerob commented Sep 5, 2018

Done! :0D

I've changed the other publish function too, also changed my code from the first posting and added an option to activate the new behavior. :0)

I work with polling now... I don't know if it is a good idea, but it works for now. If someone has some thoughts about how that affects performance, I would be very glad. :0D

Here are my additions to the publish functions:

First 'tabular_genericPub', here I changed the options handed over to the collection.find()

  var findOptions = {fields: fields};

  //Check if user is using a view as a collection. If yes, disable oplog and set polling interval.
  if(table.options.isCollectionAView === true){
    findOptions.pollingIntervalMs = 10000;
    findOptions.disableOplog = true;
  }

  return table.collection.find({_id: {$in: ids}}, findOptions);

On the 'tabular_getInfo' publish function, I added the option too, since the old code works on standard collections. :0D Now it looks like this:

  let updateRecords = () => {

    // This is to get changed ids from Views too.
    if(table.options.isCollectionAView === true) {
        filteredRecordIds = filteredCursor.map(doc => doc._id);
    }
    
    let currentCount;
    if (!table.skipCount) {
      if (typeof table.alternativeCount === 'function') {
          currentCount = table.alternativeCount(selector);
      } else {
          currentCount = countCursor.count();
      }
    }

    // From https://datatables.net/manual/server-side
    // recordsTotal: Total records, before filtering (i.e. the total number of records in the database)
    // recordsFiltered: Total records, after filtering (i.e. the total number of records after filtering has been
    // applied - not just the number of records being returned for this page of data).

    const record = {
      ids: filteredRecordIds,
      // count() will give us the updated total count
      // every time. It does not take the find options
      // limit into account.
      recordsTotal: table.skipCount ? fakeCount : currentCount,
      recordsFiltered: table.skipCount ? fakeCount : currentCount
    };

    if (recordReady) {
      //console.log('changed', tableName, record);
      this.changed('tabular_records', tableName, record);
    } else {
      //console.log('added', tableName, record);
      this.added('tabular_records', tableName, record);
      recordReady = true;
    }
  };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant