Meteor 1.3 Importing / Exporting Collections

Greetings,

I am learning the new features available in meteor 1.3 such as the modules and ecmascript package.

My question is, what is the best way to work with imports and exports in regards to where and when to include collections? For example if I am wanting to publish the collection what is the best way to export the collection and make it available to the via exports in order to import it to my publications. ?

Overall if someone has an example or a demo of how they are working with the new modules package that would be great as well.

1 Like

I have my collection + methods exported in universal code, and import it across client and server as needed :slight_smile:

Thatā€™s a good point. If I may ask do you have an example either gist or
github project I could take a look at ?

const Rooms = new Mongo.Collection('rooms')

Meteor.methods({
	insertRoom(data) {
		if(!this.userId)
			throw new Meteor.Error('unauthorized')

		Rooms.insert({
			name:data.name,
			createdBy:this.userId,
			createdAt:Date.now()
		})
	},

	removeRoom(id) {
		if(!this.userId)
			throw new Meteor.Error('unauthorized')

		if(!id)
			throw new Meteor.Error('invalid id')

		Rooms.remove({
			_id:id, 
			createdBy:this.userId
		})
	}
})

export default Rooms

Import

import Rooms from '/common/imports/collections/rooms'

Rooms._ensureIndex({name:1}, {unique:1})

Meteor.publish('rooms', function() {
	return Rooms.find()
})

Meteor.publish('room', function(name) {
	if(!name)
		return this.ready()

	Rooms.update({name, users:{$nin:[this.userId]}}, {$push:{users:this.userId}})

	this.onStop(() => Rooms.update({name}, {$pull:{users:this.userId}}))

	return Rooms.find({name})
})

Client side import donā€™t do anything outside of what you see here :slight_smile: I am not utilising modules fully tho, as Iā€™m unsure about HTML and CSSā€¦

4 Likes

Thank you, truly appreciated. This example is perfect.

1 Like

Iā€™m sorry to sort of hijack this thread, but this is the closest thing to my issue.
Using your answer I can now declare collections without a hitch. However when trying to subscribe to a published collection in a client file, the reference is not defined:

//collections.js
    const Test = new Mongo.Collection("test");
    if(Meteor.isServer){
        Test.insert({name: "Song", createdAt: new Date()});
        Test.insert({name: "Sing", createdAt: new Date()});
        Test.insert({name: "Sang", createdAt: new Date()});
    }
    export default Test;

//server.js
import Test from '/lib/collections.js';
const machin = Meteor.publish("test", function(){
   Test.find(); 
});

//client.js
const handle = Meteor.subscribe("test");
console.log(handle);

if(handle.ready()){
    const post = Test.findOne();
}

console.log(Test.findOne()); // Result: Test Reference is not defined

(Those are all different files)
Is there some way to import my subscribed collection?
Thank you.

  • put collections.js inside the /imports directory - Iā€™m not sure this is required, but it makes sense only to use it when imported.
  • your publish function should return something.
  • you need to import your Test collection on the client aswell.

something like this:

imports/collections/items.js

const Items = new Mongo.Collection('items')

if(Meteor.isServer) {
    Items.insert({name: "one", createdAt: new Date()})
    Items.insert({name: "two", createdAt: new Date()})
    Items.insert({name: "three", createdAt: new Date()})
}

export default Items

server/collections/items.js

import Items from '/imports/collections/items'

Meteor.publish('items', function() {
    return Items.find()
})
```

client/items.js

```
import Items from '/imports/collections/items'

Meteor.subscribe('items', function() {
    console.log(Items.find.fetch())
})
```
1 Like

Good evening, and thank you for taking the time.
I tried your solution, however in my server file :

import Test from ā€˜/imports/collections.jsā€™;
const handle= Meteor.publish(ā€œtestā€, function(){
Test.find();
});
console.log(handle); //undefined
</>code>

Handle here returns undefined

and in my client file

import Test from ā€˜/imports/collections.jsā€™;

const handle = Meteor.subscribe(ā€œtestā€);
console.log(handle);

if(handle.ready()){
console.log(Test.findOne());
}

It displays nothing in the console (guess itā€™s because of the condition on handle?) but when I type ā€œtestā€ in the console, it reads as Reference undefined, although the variable is visible.

  • subscriptions return handles, publish functions do not :sunny:
  • youā€™re still not returning anything from your publish. you need to return Test.find() instead.

Iā€™ve added a more clear example above. Hope this helps!

Yes - when importing/exporting, youā€™re not exposing your Test variable globally, so it is not accessible through the console.

try using a callback (like in my example above, in the first answer) instead of using the handle, itā€™s a much easier way to test this IMO :wink: the callback will only run on success (when the sub is ready) and print them for you!

1 Like

Tried your example, copy pasted it literally, here is the result:

And I have no idea what _items2 means.
Iā€™m starting to think the issue is with the base repo Iā€™m using,

Made an new project with 1.3 beta 8, and set it up in 2 minutesā€¦ Works great :confused: Iā€™m not sure what youā€™re doing wrong

Hello again,
could I please trouble you to try your method using https://github.com/PeterChauYeg/meteor-react-base ? I forgot to mention that Iā€™m using this as a starter project and Iā€™m beginning to think the problem lies with this repo.

Can you make a repo that reproduce your problem? Itā€™ll be easier for us to identify the cause of the error with a repo.

Here: https://github.com/Unforgiven-wanda/meteorIssue

Actually the error thrown by your first code snippet is totally unrelated and different from your provided repo. In your first code snippet, you didnā€™t import Test on top of your client.js. Thatā€™s why you get the error Test reference is not defined.

For your repo, you got a syntax error in your items.js

console.log(Items.find.fetch())

Note the missing bracket after find. It should be like this

console.log(Items.find().fetch())
2 Likes

Thank you. Although by now I am totally confused about Meteor. Better to start again from scratch.
Good day to you.

I agree youā€™d gain a lot more from starting with an empty project, and working your way up from there :sunny: Iā€™ve never used these boilerplates - but I guess they make sense if you want to save time.

try to use the meteor guide & the docs as much as you can - These are great resources!

what are you confused about?

Well for one your solution makes it hard to access a collection. When learning Meteor, I learned that once subscribed, a collection could be accessed from any file (provided it ran in the client), your solution makes that yes, data is displayed, but when I try to access it from the console in the browser, I still just get a measly Reference not Defined.

But I think that the issue really stems from the repo, given that any other example Iā€™ve tried works flawlessly. Iā€™ve been going over the starter code but I havenā€™t been able to find what ticks, and at this point Iā€™m just too frustrated to continue. What I truly needed to begin with was a starter project using React and Material-ui and just enough organized code to get me started.

Iā€™ll follow your advice, take it again from scratch and start on solid foundation this time.
Again, thank you for taking the time.

hehe, I understand the handiness of accessing collections from the console, but this is just not an option with 1.3 if you export your collections - with modules, your not exposing your exports to the global namespace - which means theyā€™re not accessible in the console :slightly_smiling: but theyā€™re definitely accessible anywhere - just remember to import dependencies!

1.3 is still in beta for ~a month, so the guidelines for it isnā€™t in the docs nor the guide yet, but itā€™s comingā€¦

3 Likes

Now I wish I could kidnap you for a month so you could teach me ^^ā€™

1 Like