ReferenceError - what am I doing wrong/don't I understand correctly


#1

I want to preload data in the To Do App in the tutorial (the Blaze version)

My dir/file structure is:

simple-todos
  |
 +- client
  |  +- main.cs
  |   +- main.html
  |   +- main.js
 +- api
 |    +- tasks.js
 +- ui
 |    +- body.html
 |    +- body.js
 +- package.json
 +- server
      +- main.js

The only difference with my code and the tutorial is in /server/main.js

import { Meteor } from 'meteor/meteor';

import '../imports/api/tasks.js';

Meteor.startup(() => {
  // code to run on server at startup

  // start up function that creates entries in the Websites databases.
  // code to run on server at startup
  if (!Tasks.findOne()){
    console.log("No tasks yet. Creating starter data.");
    	Tasks.insert({
        text: "Hello world!",
        createdAt: new Date()
      });
    }
});

But I keep on getting :

W20160520-08:42:51.801(2)? (STDERR) at server/main.js:10:8
W20160520-08:42:51.800(2)? (STDERR) ReferenceError: Tasks is not defined
W20160520-08:42:51.801(2)? (STDERR) at /Users/johannesdejong/Meteor.projects/simple-todos/.meteor/local/build/programs/server/boot.js:290:5

If I read (understand) the load order correctly Load Order
/server.main.js should be loaded last and thus after /imports/api/tasks.js where the collection Tasks is defined.

Surely Tasks should be known/visible by then?

Thanks for taking the time to read this.


#2

If you want to use ES2015 import / export you have to import the Tasks-Symbol in your main.js file:

import Tasks from '../imports/api/tasks.js';

and within tasks.js:

export default Tasks = new Meteor.Collection(....)


#3

Thanks macrozone.

I though import ‘…/imports/api/tasks.js’; made Tasks visible.
Do I need to still keep the import ‘…/imports/api/tasks.js’; line in my code ?

The original error is solved.

I’m now getting this error : TypeError: Cannot call method ‘findOne’ of undefined

On this line: if (!Tasks.findOne()){

Johannes


#4

It depends.

Before meteor 1.3 any file would be evaulated (in a specific order). If you declare variables without var, let or const in a file, this means this variable is global (or at least package scope), but the availability of this variable is dependent on the load-order.

With meteor 1.3 this is still possible, but you can change the load order by importing files like you did.

So if you have declared the Tasks-variable as global in ../imports/api/tasks.js, then your code should work.

Maybe its best to show us the code in tasks.js


#5

Sorry for the delay work got in the way this weekend.
No time for my new hobby :frowning:

Here the code in tasks.js

import { Mongo } from 'meteor/mongo';

export const Tasks = new Mongo.Collection('tasks');

#6

You are exporting a named constant, so the correct syntax for your server-side import is:

import { Tasks } from '/imports/api/tasks';

#7

Thanks Rob. Works now. :grin:

I will have to do some serious studying/reading up.

For one I tried both your import

import { Tasks } from '/imports/api/tasks';

and

import { Tasks } from '../imports/api/tasks.js';

Both work. Which confuses the heck out of me.
Will need to get to understand the finer points to become good at this.