Meteor-Community-Packages / ground-db

GroundDB is a thin layer providing Meteor offline database and methods
https://atmospherejs.com/ground/db
MIT License
572 stars 77 forks source link

Collection Helpers #180

Open KiwiKilian opened 7 years ago

KiwiKilian commented 7 years ago

I'm completely new to ground:db and grounded succesfully my database in a cordova app. The app only needs to read, no operations to the database are needed. But I'm using a lot of Collection Helpers (dburles:collection-helpers ) which can't be accessed when grounded (says they are not defined), because the functions aren't attached to the object returned when taken frome the grounded collection. Also I can't attach Collection Helpers to Ground.Collection (says GroundedCollection.helpers is not defined).

export const Artworks = new Mongo.Collection('artworks');

if(Meteor.isCordova){
    const  ArtworksGround = new Ground.Collection(' ArtworksGround');

    ArtworksGround.observeSource(Artworks.find());

    Meteor.subscribe('artworks.all');

    Artworks.find = function(...args) {
        return  ArtworksGround.find(...args);
    };

    Artworks.findOne = function(...args) {
        return  ArtworksGround.findOne(...args);
    };
}

Artworks.helpers({
    helperFunction() {
        // do something...
        return something;
        }
});

I know this problem is connected with the other package but I thought it would be likelier somebody around here knows a workaround for this.

richardgsands commented 6 years ago

I'm trying to figure out a way to do this too. Tried adding the helpers function to Ground.Collection.prototype, and then setting Mongo.Collection helpers on there, but it doesn't seem to work... probably some sneaky scoping issue!! Any assistance would be very much appreciated :)

// dburles:collection-helpers for Ground.Collection
// https://github.com/dburles/meteor-collection-helpers/blob/master/collection-helpers.js
Ground.Collection.prototype.helpers = function(helpers) {
    var self = this;

    if (self._transform && ! self._helpers)
      throw new Meteor.Error("Can't apply helpers to '" +
        self._name + "' a transform function already exists!");

    if (! self._helpers) {
      self._helpers = function Document(doc) { return _.extend(this, doc); };
      self._transform = function(doc) {
        return new self._helpers(doc);
      };
    }

    _.each(helpers, function(helper, key) {
      self._helpers.prototype[key] = helper;
    });
};

function _ground(collection, selector) {

    // new references to find and findOne
    collection.findOnline = collection.find;
    collection.findOneOnline = collection.findOne;

    // setup ground collection
    collection.groundCollection = new Ground.Collection(`_${collection._name}`);
    collection.groundCollection.observeSource(collection.find(selector || {}));

    // override find and findOne with ground collection functions
    collection.find = collection.groundCollection.find;
    collection.findOne = collection.groundCollection.findOne;

    // add helpers
    if (collection._helpers.prototype)
         collection.groundCollection.helpers(collection._helpers.prototype);

}

_ground(MyCollection);

The result of that is the MyCollection.findOneOnline().myHelper() works but MyCollection.findOne().myHelper() throws an error:

TypeError: MyCollection.findOne().myHelper is not a function. (In 'MyCollection.findOne().myHelper()', 'MyCollection.findOne().myHelper' is undefined)
richardgsands commented 6 years ago

Update: MyCollection.findOneOnline (i.e. the normal ungrounded version) returns a Document, whereas MyCollection.findOne (the grounded collection find method) returns an Object... watch this space!

ashish979 commented 6 years ago

@richardgsands I am facing the same problem. Are you able to solve this?