Search code examples
javascriptmeteoriron-router

How to get a list of files to the template in Meteor?


New to meteor, I'm having a hell of a time with the whole client/server thing. Super fun.

I want to read a list of all files that are in a folder, and just print them on the UI, on a template. It has to be possible. Here's the code.

js file:

var availableFiles = [];
if (Meteor.isServer) {
    var fs = Npm.require('fs');
    availableFiles = fs.readdirSync(process.env.PWD + '/public/uploads');
    console.log(availableFiles);
}

Router.map(function() {

    this.route('home', {
        path: '/',
        template: 'home',
        data: {files: availableFiles}
    });
});

html file:

<template name="home">
{{#each data.files}}
    {{this}}
{{/each}}
</template>

I've tried to put the fs calls inside a function on data on the route definition, but I get "Npm is not defined" errors. I don't know if that's how it should be structured or not, remember, newb here. Any help would be greatly appreciated.


Solution

  • I'd probably do this with a reactive array (http://reactivearray.meteor.com/) and a Meteor method. Something like:

    if (Meteor.isServer) {
        var fs = Npm.require('fs');
        Meteor.methods({
            getFiles() {
                return fs.readdirSync(process.env.PWD + '/public/uploads');
            }
        });
    }
    
    if( Meteor.isClient ) {
        Template.home.onCreated( function() {
            Template.instance().files = new ReactiveArray();
            Meteor.call('getFiles', function(error, result) {
                if( error ) {
                    console.log( error );
                } else {
                    Template.instance().files = files.concat( result );
                }
            });
        });
        Template.home.helpers({
            files() {
                return Template.instance().files.array();
            }
        });
    }
    
    Router.map(function() {
    
        this.route('home', {
            path: '/',
            template: 'home',
            data: {files: availableFiles}
        });
    });
    

    Syntax might not be perfect, but that should get the point across. You'll also need to change your template to {{#each files}}