0

In a node.js with express I'd like to define a footer such as (in layout.jade)

footer
  p © Me 2015 - Your IP: #{currentIP}

in app.js, I have:

app.locals.currentIP = function(req) {
  return req.ip;
}

When run I get the following error:

>    29|     block content    30|     footer
>  > 31|       p © Me 2015 - Your IP: #{currentIP()}    32|    33|     script(
> src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js'
> )    34|     script( src='javascripts/bootstrap.js' )
> 
> Cannot read property 'url' of undefined    at app.locals.currentIP
> (c:\workspaces\nodejs.workspace\express_website\app.js:66:13)    at
> eval (eval at <anonymous>
> (c:\workspaces\nodejs.workspace\express_website\node_modules\jade\lib\index.js:218:8),
> <anonymous>:199:69)    at eval (eval at <anonymous>
> (c:\workspaces\nodejs.workspace\express_website\node_modules\jade\lib\index.js:218:8),
> <anonymous>:225:22)    at res
> (c:\workspaces\nodejs.workspace\express_website\node_modules\jade\lib\index.js:219:38)
> at Object.exports.renderFile
> (c:\workspaces\nodejs.workspace\express_website\node_modules\jade\lib\index.js:380:38)
> at Object.exports.renderFile
> (c:\workspaces\nodejs.workspace\express_website\node_modules\jade\lib\index.js:370:21)
> at View.exports.__express [as engine]
> (c:\workspaces\nodejs.workspace\express_website\node_modules\jade\lib\index.js:417:11)
> at View.render
> (c:\workspaces\nodejs.workspace\express_website\node_modules\express\lib\view.js:126:8)
> at tryRender
> (c:\workspaces\nodejs.workspace\express_website\node_modules\express\lib\application.js:639:10)
> at EventEmitter.render
> (c:\workspaces\nodejs.workspace\express_website\node_modules\express\lib\application.js:591:3)

What's wrong?

Sandman42
  • 73
  • 1
  • 1
  • 10
  • possible duplicate of [Express.js: How can I get the ip Address and render a view?](http://stackoverflow.com/questions/25192216/express-js-how-can-i-get-the-ip-address-and-render-a-view) – Swaraj Giri Aug 05 '15 at 09:24
  • Maybe, but I've did it like the link recommends, but it does not work. I also have app.enable('trust proxy'); although not mentioned. – Sandman42 Aug 05 '15 at 09:27

1 Answers1

1

According to official doc

app.locals properties persist throughout the life of the application, in contrast with res.locals properties that are valid only for the lifetime of the request.

In your case it would be better to use res.locals.currentIP instead app.locals.currentIP because lifetime of ip is bound to request rather than application life cycle:

To pass a current user's ip to a view just use:

app.post('/get/ip/address', function (req, res) {
    res.locals.currentIP = req.ip
    ...
});

In a view you have to use the following snippet to output an accepted ip address.

footer
  p &copy; Me 2015 - Your IP: #{locals.currentIP}

The error Cannot read property url of undefined at app.locals.currentIP due to your currentIP() fucntion get executes in another context. My suggestion is don't use function for outputting current user's ip but use scalar value as my code above shows.

You could reside res.locals.currentIP in a middleware to get access to currentIP variable in all of your views like the following:

var express = require('express');
var app = express();

app.enable('trust proxy');

app.use(express.static(__dirname + '/public'));

app.use(fucntion (req, res, next) {
   res.locals.currentIP = req.ip;
   next();
});

// routes does after the middleware !
// ...

app.listen(process.env.PORT || 3000);

Note that your route definitions should be after the middleware that populates res.locals.currentIP.

  • Ok. I agree with you, but it doesn't work, although it gives no error. Since I want to put it in a footer, so every page should show it, I've put the footer in layout.jade, but where should I put res.locals??? I don't want to put it available on a specific page, like your example, but in the footer. – Sandman42 Aug 05 '15 at 10:35
  • You should put `res.locals` either in specific route or in a middleware. I've updated my answer – Artem Baranovskii Aug 05 '15 at 10:38