robfallows / tunguska-reactive-aggregate

Reworks jcbernack:reactive-aggregate for ES6/ES7 and Promises
MIT License
51 stars 27 forks source link

Aggregation with $lookup is not publishing. #68

Open mlanning opened 2 years ago

mlanning commented 2 years ago

I think I have this looking the same as the documentation, but I am getting an error and no data is being published.

I have two mongodb collections named swapBuckets and locations. I would like to aggregate a location property on the swapBucket by looking up the location by locationId. This is what the data looks like in the database.

    db.swapBuckets.find().pretty();
    {
        "_id" : "rcmiajXkYBDWdYmjL",
        "capacity" : "5 gallon",
        "color" : "white",
        "contentStatus" : "empty",
        "locationId" : "jNjewKekCmhwTgL9d",
    }

    db.locations.find().pretty();
    {
        "_id" : "jNjewKekCmhwTgL9d",
        "name" : "Nourish Organic Juice",
        "number" : 1,
    }

I am publishing them in my Meteor app like this...

    import { ReactiveAggregate } from "meteor/tunguska:reactive-aggregate";
    import { SwapBucketsCollection } from "/imports/api/SwapBuckets/collection";    

    if (Meteor.isServer) {
      Meteor.publish("swapBucketsLocation", function () {
        ReactiveAggregate(
          this,
          SwapBucketsCollection,
          [
            {
              $lookup: {
                from: "locations",
                localField: "locationId",
                foreignField: "_id",
                as: "location",
              },
            },
          ],
          { clientCollection: "swapBucketsWithLocation" }
        );
      });
    }

On the client side ui (Vue.js 2), I have this in the component...

    <script>
    const SwapBucketsWithLocation = new Mongo.Collection('swapBucketsWithLocation');

    export default {
      meteor: {
        $subscribe: {
          swapBucketsLocation: []
        },
        swapBuckets() {
          const swapBuckets = SwapBucketsWithLocation.find({}, { sort: { number: 1 } }).fetch();
          if (swapBuckets) {
            return swapBuckets;
          }
          return [];
        },
      },
    };
    </script>

When I look at Meteor dev tools in Chrome, there are no entries in the SwapBucketsWithLocation collection. It is created, but it is empty. In the server console, I am getting the following error...

    I20220719-10:30:42.656(-6)? Exception from sub swapBucketsLocation id ACiiCuPna7WE72GB8 TypeError: Cannot convert undefined or null to object
    I20220719-10:30:42.657(-6)?     at Function.entries (<anonymous>)
    I20220719-10:30:42.658(-6)?     at ReactiveAggregate (packages/tunguska:reactive-aggregate/aggregate.js:56:37)
    I20220719-10:30:42.658(-6)?     at Subscription._handler (imports/api/SwapBuckets/publications.js:10:5)
    I20220719-10:30:42.658(-6)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1885:12)
    I20220719-10:30:42.659(-6)?     at packages/ddp-server/livedata_server.js:1107:9
    I20220719-10:30:42.659(-6)?     at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1257:12)
    I20220719-10:30:42.659(-6)?     at Subscription._runHandler (packages/ddp-server/livedata_server.js:1106:60)
    I20220719-10:30:42.659(-6)?     at Session._startSubscription (packages/ddp-server/livedata_server.js:917:9)
    I20220719-10:30:42.659(-6)?     at Session.sub (packages/ddp-server/livedata_server.js:673:12)
    I20220719-10:30:42.660(-6)?     at packages/ddp-server/livedata_server.js:603:43

It seems like this is a pretty basic aggregation, but I either have something wrong, or there is a bug in the package. Any help or ideas would be greatly appreciated.

robfallows commented 2 years ago

There is at least one typo in your example:

{ clientCollection: swapBucketsWithLocation" } is missing an opening quote around swapBucketsWithLocation.

However, I think this may be a transcription error. I don't use Vue, so can't really comment sensibly on the syntax you have.

In any case, please provide a minimum repro exhibiting the problem, so I can investigate properly. Thank you 🙂

mlanning commented 2 years ago

Ah, yes. That's just a transcription error. I've fixed it in the post now. Thanks for pointing it out.

I'll get a working example for you soon, as time permits. I don't think the Vue part matters as much because I'm not even seeing the data being published to minimongo, (using chrome dev tools Meteor extension). In any case, thanks for taking the time. I'll be back with the example soon.

jdalrymple commented 2 years ago

Im getting a similar error, however im not passing a lookup. Is it possible there is an error in the code? Particularly line 56:

  for (const [name,value] of Object.entries(options.specificWarnings)) {
    if (typeof value !== 'boolean') throw new TunguskaReactiveAggregateError(`"options.specificWarnings.${name}" must be true or false`);
  }

Shouldnt it be Object.entries(localOptions.specificWarnings)) ?