0

I have a pdf file located here:

/server/.files/users/test.pdf

When I display a link on a page, I'd like for the user to be able to click the link, and for the pdf to be rendered on the screen.

I've read through this SO post in particular, and others, but cannot seem to get things to work: SO Link

I tried using an IR route server side, but every time I try even something simple I get the following error:

Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions. at Object.Meteor.userId

(packages/accounts-base/accounts_server.js:19:1) at Object.Meteor.user (packages/accounts-base/accounts_server.js:24:1) at [object Object].Router.onBeforeAction.except (app/both/3-router/routes.js:10:15) at packages/iron:router/lib/router.js:277:1 at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1) at [object Object].hookWithOptions (packages/iron:router/lib/router.js:276:1) at boundNext (packages/iron:middleware-stack/lib/middleware_stack.js:251:1) at runWithEnvironment (packages/meteor/dynamics_nodejs.js:108:1) at packages/meteor/dynamics_nodejs.js:121:1 at [object Object].dispatch (packages/iron:middleware-stack/lib/middleware_stack.js:275:1)

Line: #10 in my router.js file is the first if statement here:

Router.onBeforeAction(function () {   
   if (!Meteor.user() || Meteor.loggingIn()) {
    this.redirect('welcome.view');   }   else {
    Meteor.call("userFileDirectory", function (error, result) {
      if (error)
        throw error;
      else
        console.log(result);
    });
    this.next();   
 } }, {   except: ['welcome.view'] });

I tried this:

Router.map(function() {
    this.route('serverFile', {
        where: 'server',
        path: /^\/uploads_url_prefix\/(.*)$/,
        action: function() {
           var filePath = process.env.PWD + '/.files/users/' + this.params[1];
           var data = fs.readFileSync(filePath);
           this.response.writeHead(200, {
                'Content-Type': 'image'
           });
           this.response.write(data);
           this.response.end();
        }
    }); });

But I'm not sure what to put in the path.

Community
  • 1
  • 1
Aaron
  • 3,068
  • 2
  • 21
  • 44
  • II never needed sth liek this so I can;t help you, but maybe in new iron-router api there will be answer for ur question https://github.com/EventedMind/iron-router/blob/devel/Guide.md – sdooo Dec 27 '14 at 02:16

1 Answers1

2

With process.env.PWD you are in the directory of your meteor project. so you should be able to access your file like this:

var file = process.env.PWD + "/server/.files/users/test.pdf"

To use the fs package of node you also need to include it and you need to be on the server:

Router.route('/pdf', function() {
    var filePath = process.env.PWD + "/server/.files/users/test.pdf";
    var fs = Meteor.npmRequire('fs');
    var data = fs.readFileSync(filePath);
    this.response.write(data);
    this.response.end();
}, {
    where: 'server'
});

Make sure to this package to your project (https://atmospherejs.com/meteorhacks/npm)

meteor add meteorhacks:npm

I tested it and it is working like a charm!

PhilippSpo
  • 789
  • 7
  • 10
  • I'll give you the answer, as the question primarily dealt with the rendering of the pdf and not the exception (although even with your code the exception is still occurring, yet when I take it out, your method works), with one caveat: you don't need meteorhacks:npm to call npm packages, just replace the line Meteor.npmRequre('fs') with Npm.require('fs'), and your code works fine (I've also got Npm.require working all over my server side code (at least with the latest version of Meteor). – Aaron Dec 29 '14 at 16:15