Meteor + express should work the way Nodejs works with express

I have been killing myself trying to get Meteor to do what I can do on Nodejs. all I want to do is upload files to my public folder. I can do it if I run Nodejs alone. but can’t get the same functionality from meteor. Meteor is making my work harder. I don’t want to use a collection like CollectionsFS (dead or will be dead.)
If anyone knows how to get files uploaded into the public folder from a form or input, then please share with me. If I figure this out I will be posting it everywhere I can. there are no documents on the meteor site that touches this

You do realize Meteor is built on Node, uses Node modules (that are available to you as well) and can run NPM packages right? Anything that you can do in Node, you can do in Meteor. You can also run an express server on a different port within the same process.

I don’t really understand. What’s the issue?

1 Like

You can use WebApp.connectHandlers and npm formidable.

See this code :

import {Meteor} from 'meteor/meteor';
import {WebApp} from 'meteor/webapp';
import pathToRegexp from 'path-to-regexp';
import formidable from 'formidable';
import util from 'util';
import fs from 'fs';
import path from 'path';

WebApp.connectHandlers.use('/', (req, res, next) => {
    const matchPath = matchPathFactory(req);

    if (matchPath('/server/upload')) {
        const form = new formidable.IncomingForm();

        form.parse(req, (err, {namespace, status = 'new'}, files) => {
            //Here, we already have the files.
            //Then save your files to your folder.
            saveFilesToFolder(files);
        });
    }
});


//If we just return matchPath, it doesn't work.
//So we use this hack.
function matchPathFactory(req) {
    if (req.keys || req.segments || req.params) {
        throw 'keys or segments or params already defined';
    }
    return matchPath.bind(req);

    function matchPath(pattern) {
        if (this.url === undefined) {
            throw 'Please bind this to req';
        }

        this.keys = [];
        this.segments = pathToRegexp(pattern, this.keys).exec(this.url);
        this.params = {};
        if (this.segments && this.segments.length > 1) {
            this.keys.forEach((item, index) => {
                this.params[item.name] = this.segments[index + 1];
            });
        }

        return this.segments;
    }
}

function saveFilesToFolder(files){
    //Code to save files to folder
}
2 Likes

Thank you for the helping hand.

Had this same question. Thank you @agusputra for the lead.

Basically, you can import Express, create a new express app instance, and pass it into WebApp.connectHandlers:

...
import express from 'express';
const app = express();
WebApp.connectHandlers.use(app);
...

In case it’s helps, I wrote a tutorial about setting up Express within a Meteor app: http://www.mhurwi.com/meteor-with-express/

6 Likes