i have a problem on running the heroku sample application online , it works perfectly locally , but on heroku it shows this error :
TypeError: /app/views/index.ejs:7
5| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes" />
6|
>> 7| <title><%= app.name %></title>
8| <link rel="stylesheet" href="stylesheets/screen.css" media="Screen" type="text/css" />
9| <link rel="stylesheet" href="stylesheets/mobile.css" media="handheld, only screen and (max-width: 480px), only screen and (max-device-width: 480px)" type="text/css" />
10|
Cannot read property 'name' of undefined
at Object.<anonymous> (eval at <anonymous> (/app/node_modules/ejs/lib/ejs.js:198:12))
at Object.<anonymous> (/app/node_modules/ejs/lib/ejs.js:200:15)
at ServerResponse._render (/app/node_modules/express/lib/view.js:422:21)
at ServerResponse.render (/app/node_modules/express/lib/view.js:315:17)
at /app/web.js:49:11
at [object Object].me (/app/node_modules/faceplate/index.js:114:7)
at /app/web.js:48:18
at /app/node_modules/faceplate/index.js:104:7
at EventEmitter.<anonymous> (/app/node_modules/faceplate/index.js:131:11)
at EventEmitter.emit (events.js:70:17)
I read somewhere that may be a problem with dependencies in package.json so here is my package.json file :
{
"name": "facebook-template-node",
"version": "0.0.1",
"description": "Template app for Heroku / Facebook integration, Node.js language",
"dependencies": {
"async": "0.1.18",
"ejs": "0.4.3",
"express": "2.4.6",
"faceplate": "0.6.x"
},
"engines": {
"node": "0.6.x"
}
}
and here's the code of web.js :
var async = require('async');
var express = require('express');
var util = require('util');
// create an express webserver
var app = express.createServer(
express.logger(),
express.static(__dirname + '/public'),
express.bodyParser(),
express.cookieParser(),
// set this to a secret value to encrypt session cookies
express.session({ secret: process.env.SESSION_SECRET || 'secret123' }),
require('faceplate').middleware({
app_id: process.env.FACEBOOK_APP_ID,
secret: process.env.FACEBOOK_SECRET,
scope: 'user_likes,user_photos,user_photo_video_tags'
})
);
// listen to the PORT given to us in the environment
var port = process.env.PORT || 3000;
app.listen(port, function() {
console.log("Listening on " + port);
});
app.dynamicHelpers({
'host': function(req, res) {
return req.headers['host'];
},
'scheme': function(req, res) {
return req.headers['x-forwarded-proto'] || 'http';
},
'url': function(req, res) {
return function(path) {
return app.dynamicViewHelpers.scheme(req, res) + app.dynamicViewHelpers.url_no_scheme(req, res)(path);
}
},
'url_no_scheme': function(req, res) {
return function(path) {
return '://' + app.dynamicViewHelpers.host(req, res) + (path || '');
}
},
});
function render_page(req, res) {
req.facebook.app(function(err, app) {
req.facebook.me(function(user) {
res.render('index.ejs', {
layout: false,
req: req,
app: app,
user: user
});
});
});
}
function handle_facebook_request(req, res) {
// if the user is logged in
if (req.facebook.token) {
async.parallel([
function(cb) {
// query 4 friends and send them to the socket for this socket id
req.facebook.get('/me/friends', { limit: 4 }, function(friends) {
req.friends = friends;
cb();
});
},
function(cb) {
// query 16 photos and send them to the socket for this socket id
req.facebook.get('/me/photos', { limit: 16 }, function(photos) {
req.photos = photos;
cb();
});
},
function(cb) {
// query 4 likes and send them to the socket for this socket id
req.facebook.get('/me/likes', { limit: 4 }, function(likes) {
req.likes = likes;
cb();
});
},
function(cb) {
// use fql to get a list of my friends that are using this app
req.facebook.fql('SELECT uid, name, is_app_user, pic_square FROM user WHERE uid in (SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user = 1', function(result) {
req.friends_using_app = result;
cb();
});
}
], function() {
render_page(req, res);
});
} else {
render_page(req, res);
}
}
app.get('/', handle_facebook_request);
app.post('/', handle_facebook_request);
You seem to be using the res.render function, however don't seem to be passing it the app object. I believe (unless I'm missing something) that you need to pass the app object to the render function. For example:
res.render('view_name', { app: { name: 'Site_Name' } } );
The other option, if you are using app in a large number of your views, is to add the app object too app.locals, which will make it available in all views (rendered from the current app). This can be done as:
app.locals({
app: {
name: 'Site_Name'
}
});
and then you do not need to pass app to each render call, and
res.render('view_name', {} );
should work.
This is an issue with Facebook's application security and is addressed here:
Heroku - Created a facebook app with Node.js which gives type error
I got it working by disabling sandbox mode on my app.