Importing dynamic file in a module


#1

I have a file which is being updated with a cron job. I have a module where I want to use data from this file. I can’t use import because then it compiles this file into single JS file in bundle which I cannot update. I also need this file to be included synchronously because I use it in module like below and it’s being called in another file

export const x = function(){

}

Is there any way to do it? I use Meteor 1.3 with React.


#2

I think we need more sample code to understand your scenario.

It sounds like you would want to import javascript-code that is generated by a cronjob.

injecting code during runtime is possible in Javascript, however it is not recommended in general. Maybe loading data is enough (without logic) that you can store in the database, in a json-file or in a csv-file?


#3

I have a JSON file which is being updated automatically with a cron job every X hours.

My structure is like this:

methods.js

//Somehow read content from JSON file
// Option 1 from DB: let JSONData = Settings.find().fetch();
// Option 2 : import?
export const list1 = JSONData.list1;
export const list2 = JSONData.list2;

Then I have a file where I actually require this data, as below:

import {list1, list2} from 'methods';
//Do something with these variables

Problem is- if I use option 1 and read from database, it is empty on the client side at the time its being rendered as I need to subscribe to the collection first and wait for callback. Any way to make a collection always public?

If I use option 2 I am not sure how to import the file. If I use like
import JSONData from 'my-data.json'
it works for the first time but I can’t update the data with my cron job because the contents of file ‘my-data.json’ are compiled to a main JS bundle file, where all scripts are bundled (when I use meteor build).

I can put this JSON file to public and then call it with jQuery etc. but it’s asynchronous also so the exported variables are empty. Any solutions?

Thanks


#4

EDIT: I think you mean you want the data on the client - in that case you’d have to call a method whenever you want to check for new data and that method would call fs.readFileSync on the server.

What are you actually trying to achieve here? There’s probably a more straightforward solution depending on the problem.


You’re looking for fs.readFileSync, part of the Node.js API. Details at https://nodejs.org/docs/v0.10.45/api/fs.html#fs_fs_readfilesync_filename_options but you basically do

import fs from 'fs';
var contents = fs.readFileSync('my-data.json', 'utf8');

btw you can make a collection always public (although it’s not actually instant, it’s still sent over the websocket, not sent with the initial html boilerplate). Just do:

Meteor.publish(null, function () { 
    return MyCollection.find({ blah... }); 
});

#5

Sorry forgot to mention. I include this file in the frontend so I cannot use fs.


#6

I would do a cronjob that imports this data into the DB. Then you can work with this data like with any other Collection in Meteor.

The behavior of the collection on the client is then exactly the same as with every other collection. You need to subscribe to data and wait for the subscription to be ready if you do not want to display empty results.

Checkout the guide on data-loading and publications: http://guide.meteor.com/data-loading.html

Option 2 is not suitable for this scenario.

Loading data with Ajax (jquery or meteor’s Http-package) is also an option (let’s call it option 3). But then you don’t have reactive-realtime-data.

There is a similar option 4: Loading the data with a Meteor.method and load the file on the server-stub of the method with node’s file-api (or maybe with http://docs.meteor.com/api/assets.html).

Client is always async and has to wait for data. But there are easy patterns to show a loading-screen or similar. Checkout the guide for that.

I would go for option 1, because it should be pretty easy and will update clients when the cronjob changed the data


#7

Thanks guys, went for data-loading and publications method.