Import an entire module's contents

I created a server side module:

// module 1

import { THE_USER } from './users'

let userId = '';
if (THE_USER) userId = THE_USER;
const query = { userId: userId }; // On startup THE_USER is undefined 

 // On startup the findOne returns undefined
let record = collection_name.findOne(query);
if (!record) record = {};

let {
  first: test1,
  second: test2,
  third: test3
} = record;

export const doSomethingCool = () => { ... }

export {
  test1, test2, test3
}

.

The variables and functions import without errors with this syntax:

// function

import ( test1, test2, test3, doSomethingCool } from '../../imports/server/module1.js

.

Yet, I have so many variables and functions within module1, I’d like to import an entire module’s contents like so:

import * as importedModule1 from '../../imports/server/module1.js

When I use this syntax I get the following error on startup:

"Error: Cannot find module '../../imports/server/module1.js"

What am I doing wrong?

I think if you do import module from '../../imports/server/module1.js'
Then you should be able to access everying like module.test1, module.test2

I don’t know what’s wrong, as the syntax I wrote looks correct from what I’ve read. But I get the error none the less. I’m still on Meteor 1.3, and ecmascript 0.4.8 if that matters.
.

Again, I get no errors with this syntax:

import ( test1, test2, test3, doSomethingCool } from '../../imports/server/module1.js

only the wildcard:

import * as importedModule1 from '../../imports/server/module1.js

.

I’ve never seen your syntax used to import everything, only to import the default variable or function.

.
I think within the module itself, if I do this

module1.exports = {
 test1, test2, test3, doSomethingCool
}

then doing this might work:

import module1 from '../../imports/server/module1.js'

but I don’t want to internally assign the variables/function to an object, if at all possible.

I’ve actually found that attaching the vars and functions can be quite helpful in cleaning up your import declarations:

// publications.js
import Docs from '/imports/lib/collections/docs';

Meteor.publish('publicDocs', function (query) {
  return Docs.find({ query }, { fields: Docs.publicFields });
});

Meteor.publish('adminDocs', function (query) {
  return Docs.find({ query }, { fields: Docs.adminFields });
});



// docs.js

const Docs = new Mongo.Collection('docs');

Docs.publicFields = {
  // only public fields
};

Docs.adminFields = {
  // all the fields
};

export default Docs;

1 Like

Interesting, in your example, would the client consume this module? What would the client’s consumption of this module look like?

Thank you taking time out to share. :smile:

Just to move this along, for now I added everything to a Docs object like so:

import { THE_USER } from './users'

let userId = '';
if (THE_USER) userId = THE_USER;
const query = { userId: userId }; // On startup THE_USER is undefined 

 // On startup the findOne returns undefined
let record = collection_name.findOne(query);
if (!record) record = {};

let {
  first: test1,
  second: test2,
  third: test3
} = record;

export const doSomethingCool = () => { ... }

const Docs = {};

Docs.First = {
  test1
}

Docs.Second = {
  test2
}

Docs.Third = {
  test3
}

Docs.Functions = {
  doSomethingCool
}

export default Docs;

I can now do the following

//

import Docs from '../../imports/server/module1.js'

Docs.First.test2 // => "some string'

// But this DOES NOT work

Docs.doSomethingCool() //=> TypeError: Object [object Object] has no method

Probably depends on your use case, but if you wanted to minimize the imports and keep things like your adminFields from hitting the client, you could do something like:

const Docs = new Mongo.Collection('docs');

Docs.publicFields = {
  // only public fields
};

const adminFields = {
  // all the fields
};

export const PublicDocs = Docs;
export const AdminDocs = _.extend(Docs, { adminFields });

Yea, it seems I’m forced to export functions like this:

// module1.js
// WORKS
export const greatFunction = () => { ... }
export const evenBetterFunction = () => { ... }

// DOESN'T WORK
const Docs = {};
Docs.functions = {
  greatFunction, evenBetterFunction // => Throws an error
};

// consuming module
import ( greatFunction, evenBetterFunction } from '../../server/module1'

Yet, I can export variables like this:

// module1.js
let {
  field1, field2, field3
} = collection1.findOne(query);

let {
  field4, field5, field6
} = collection2.findOne(query);

const Docs = {};

Docs.collection1 = {
  field1, field2, field3
};

Docs.collection2 = {
  field4, field5, field6
};

export default Docs;

// consuming module
import Docs from '../../server/module1'

What I’m wondering about is, if you’re actually sending down the Docs to your client instead of what we usually do, which is just to publish then subscribe on the client. Instead you seem not be subscribing on the client, just loading the module and retreiving the data? Is this reactive without a subscription?

No, we still use the pub/sub model, but have just found it handy to attach props to the collection object that are used all the time. Things like the fields we limit, the keys we pass into omnisearch queries, keys that we use to trigger certain functionality, etc.