Search code examples
typescriptmongodbmeteor

How to initialize server-side Meteor Collection without needing to interact with it?


I'm new to Meteor, and building a simple recipe list.

I have a file (/imports/api/recipes.ts) which defines my Recipe collection:

// imports/api/recipes.ts
export interface Recipe {
  _id?: string;
  title: string;
  createdAt: Date;
}

export const RecipesCollection = new Mongo.Collection<Recipe>("recipes");

And I can import/interact with that collection on the client side (in a React component) fairly easily.

However: Changes don't stick! Inserts flash briefly, but are then reverted in the browser when the "Optimistic UI" realizes the operation failed:

enter image description here

The only way I've been able to make this example work, is to interact with the imported collection in server/main.ts. (Not just include via a named import.)

Every example I've found explains this away by installing some "initial seed data" as a convenience - but I'm having trouble graduating this approach to something more realistic.

If I import the collection in /server/main.ts but don't touch it:

// server/main.ts
import { Meteor } from "meteor/meteor";
import { RecipesCollection } from "/imports/api/recipes";

Meteor.startup(async () => {});

The insert fails with the error in the screenshot above. However, if I do something semi-meaningless like this:

// server/main.ts
import { Meteor } from "meteor/meteor";
import { RecipesCollection } from "/imports/api/recipes";

Meteor.startup(async () => {
  console.log(`On startup, saw ${RecipesCollection.find().count()} recipes`);
});

Then the application functions as expected. Is there a more straightforward way to signal to Meteor that I'd like this collection to be "plumbed" for server-side persistence and interaction with Mongo?


Solution

  • You will always need to import collection code somewhere on the server, but not necessarily interact with it. In anything larger than just a demo this will probably happen naturally because you'll end up importing your collections so that you can write allow/deny logic, attach hooks, or use them within your Meteor methods.

    In the case of your above code a simple one line import with just the file path should work.

    import "/imports/api/recipies";
    

    Edit: It turns out the specific reason this is happening is because the typescript compiler removes imports where all references are unused.

    https://github.com/microsoft/TypeScript/issues/4717