Prerender not serving up products - angularjs

I am serving up angular pages from express. I cannot get prerender to serve up rendered pages for the products:
http://www.minilolo.com/?_escaped_fragment_=/products/Lolo-Pink
But other pages like this one are OK:
http://www.minilolo.com/?_escaped_fragment_=/products
I think I may need to add some express routes, but would like to know if I am on the right track. Thanks!
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.set('view engine', 'ejs');
app.use(require('prerender-node').set('prerenderToken', 'xyz123'));
/**
* Development Settings
*/
if (app.get('env') === 'development') {
// This will change in production since we'll be using the dist folder
app.use(express.static(path.join(__dirname, '../client')));
// This covers serving up the index page
app.use(express.static(path.join(__dirname, '../client/.tmp')));
app.use(express.static(path.join(__dirname, '../client/app')));
// Error Handling
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
/**
* Production Settings
*/
if (app.get('env') === 'production') {
// changes it to use the optimized version for production
app.use(express.static(path.join(__dirname, 'dist')));
// added to serve up products pages
app.use(function(req, res) {
// Use res.sendfile, as it streams instead of reading the file into memory.
res.sendfile(__dirname + '/dist/index.html');
});
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
}
module.exports = app;
EDIT: I have tracked down the issue to prerender converting '?_escaped_fragment_=' into '#!'. Angular then doesn't know which route to use unless I have $locationProvider.hashPrefix('!') in place (which I don't want to use). I dont want the # prefix if it can be helped.
2015-09-07T12:17:17.566Z got 200 in 12713ms for http://localhost:3000/#!/products
2015-09-07T12:17:18.773Z Timed out. Sending request with HTML on the page
2015-09-07T12:17:18.785Z got 200 in 12732ms for http://localhost:3000/#!/products
2015-09-07T12:19:04.589Z getting http://localhost:3000/#!/products

As explained on the following links:
https://github.com/prerender/prerender/issues/198
https://developers.google.com/webmasters/ajax-crawling/docs/specification?hl=en
The query from the search has '?_escaped_fragment_=' at the end of the path, rather than straight after the fqdn.
http://www.minilolo.com/?_escaped_fragment_=/products/Lolo-Pink <-- not this
http://www.minilolo.com/products/Lolo-Pink?_escaped_fragment_= <-- this!

Related

MEAN-stack app: REST API calls from angular2 frontend to express backend do not work. Error: ERR_CONNECTION_REFUSED

I am building a MEAN stack app, following this tutorial: https://www.youtube.com/watch?v=PFP0oXNNveg&t=3236s
The Problem: I try to do http.get() request from my angular2 frontend to my express backend. It does not work and i get the Error: ERR_CONNECTION_REFUSED:
The Error
My frontend is on localhost/4200 and my backend on localhost/3000. I figured the problem might be that, so i search for solutions and tried everything described in here: Angular-CLI proxy to backend doesn't work (solution to proxy the localhost port), which does not work for me. I still get the error.
here is my code :
Service method with API call
getUsers() {
return this.http.get('http://localhost/3000/api/users')
.map(res => res.json());
}
server.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var start = require('./routes/start');
var registration = require('./routes/registration');
var port = 3000;
var app = express();
//View Engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
//Set Static Folder
app.use(express.static(path.join(__dirname, 'client')));
app.use(express.static(path.join(__dirname, 'client', 'dist')));
//Body Parser MW
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/', start);
app.use('/api', registration);
app.listen(port, () =>{
console.log('Server started on port '+port);
});
The route i try to use with my API call
//get all the user
router.get('/users', function(req, res, next){
db.users.find(function(err, usrs){
if(err){
res.send(err);
}
res.json(usrs);
});
});
//get single user
router.get('/user/:id', function(req, res, next) {
db.users.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, usr){
if(err){
res.send(err);
}
res.json(usr);
});
});
//save a new user
router.post('/user', function(req, res, next) {
var user = req.body;
if(!user.name || !user.password){
res.status(400);
res.json({
"error": "Bad Data"
});
} else {
db.users.save(user, function(err, user) {
if(err){
res.send(err);
}
res.json(user);
});
}
});
module.exports = router;
I'm guessing because you're trying to go to 'http://localhost/3000/api/users' which has a / after localhost instead of a :, so you're going to localhost on port 80, which is the default. Switch it to 'http://localhost:3000/api/users', does that help?

On refreshing angularjs page gives error of page not found

I have an angular application in which when I used
$locationProvider.html5Mode(true);
for removing #! , it works good. but when I refreshes the page it gives error that
Get GET /c/electronic/computer/laptop not found which is my url
This is my app.js page
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var app = express();
app.use(function(req,res,next){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
This is my index page I putted all my functions and apis for firing queries where in models there had my mongodb's queries
var express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
Category = require('./models/category');
Product = require('./models/product');
http = require('http');
mongoose.connect('mongodb://localhost/baazaronline');
var db = mongoose.connection;
router.get('/api/category', function(req, res){
Category.getCategory(function(err, category){
if(err){
throw err;
}
res.json(category);
});
});
router.get('/api/product', function(req, res){
Product.getProduct(function(err, product) {
if(err){
throw err
}
res.json(product);
})
});
router.get('/api/product/:_id', function(req, res){
Product.getProductById(req.params._id, function(err, product){
if(err){
throw err;
}
res.json(product);
});
});
Kasun, the reason that this is occurring is because you are trying to refresh the page from one of your sub routes (has nothing to do with ui-router).
Basically if you request www.yourdomain.com/ you likely have your server setup to return index.html which bootstraps your angular app. Once the app has loaded, any further url changes take html5Mode into consideration and update your page via ui-router.
When you reload your page the angular app is no longer valid as it has not loaded yet, so if you are trying to load a sub route (for example: www.yourdomain.com/someotherpage), then your server does not know how to deal with /someotherpage and likely returns 404 or some other error.
What you need to do is configure your server to return your angular app for all routes. I primarily use node/express, so I do something like:
app.get('*', function(req, res, next) {
// call all routes and return the index.html file here
}
Note: I usually use something like this as a final catch all, however I also include other routes above it for things like requesting static files, web crawlers, and any other specific routes that need to be handled.

Angular 4 Node Mssql

I am a newbie when it comes to web development . I am currently working to get a real time web project up and running . I have a ms sql server 2014 working in my workplace and have installed node.js/ and used express generator to generate out an application . I have used mssql node module to connect and retrieve data from mssql server and it works.Although, Things that are confusing to me at this point:
how do i add angular 4 into the equation to help with the frontend development?i have already done npm install --save anular/cli but do not know where to start regarding creating input forms with drop downs whose values are to retrived from the DB .
my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
my index.js (i tried to create a connection with myssql and display a table in the index.html jade file)
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
GetData(function(recordset)
{
res.render('index', {projects: recordset })
});
});
function GetData(callback )
{
var sql = require ('mssql');
const config = {
user: 'sa',
password: 'password',
server: 'localhost\\SQLEXPRESS',
database: 'xxxxx',
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
var connection = new sql.Connection(config, function(err)
{
var request = new sql.Request(connection);
request.query('select * from Project_Type' , function(err, recordset)
{
callback(recordset);
});
});
}
module.exports = router;
Some more questions:
Is this the right place to start a sql connection ? or should i put in in the app.js file
and other advice as to how to setup the environment and angular to properly speak with the db would be highly appreciated.

Nodejs: Failed to lookup view "error" in views directory

I am currently working on an angular website running express on a nodejs server. It usually loads up perfectly when I start running it on localhost but just yesterday it suddenly started throwing this error.
GET / 500 3.467 ms - 1595
Error: Failed to lookup view "error" in views directory "C:\node\nodetest1\routes\views"
at EventEmitter.render (C:\node\nodetest1\node_modules\express\lib\application.js:579:17)
at ServerResponse.render (C:\node\nodetest1\node_modules\express\lib\response.js:960:7)
at C:\node\nodetest1\server.js:63:7
at Layer.handle_error (C:\node\nodetest1\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (C:\node\nodetest1\node_modules\express\lib\router\index.js:310:13)
at C:\node\nodetest1\node_modules\express\lib\router\index.js:280:7
at Function.process_params (C:\node\nodetest1\node_modules\express\lib\router\index.js:330:12)
at next (C:\node\nodetest1\node_modules\express\lib\router\index.js:271:10)
at Layer.handle_error (C:\node\nodetest1\node_modules\express\lib\router\layer.js:67:12)
at trim_prefix (C:\node\nodetest1\node_modules\express\lib\router\index.js:310:13)
at C:\node\nodetest1\node_modules\express\lib\router\index.js:280:7
at Function.process_params (C:\node\nodetest1\node_modules\express\lib\router\index.js:330:12)
at Immediate.next (C:\node\nodetest1\node_modules\express\lib\router\index.js:271:10)
at Immediate.<anonymous> (C:\node\nodetest1\node_modules\express\lib\router\index.js:618:15)
at runCallback (timers.js:674:20)
at tryOnImmediate (timers.js:645:5)
Here is my site directory tree:
nodetest1
bin
routes
libs
partials
views
server.js
package.json
I've been stuck on this for a day now and would really appreciate some help. Thanks!
Edit: Heres my server code below.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
//This connects the Mongo DB
//var mongo = require('mongodb');
//var monk = require('monk');
//var db = monk('localhost:27017/appointment');
mongoose.connect('mongodb://localhost:27017/appointment');
var app = express();
var index = require('./routes/index');
var users = require('./routes/users');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('ejs', require('ejs').renderFile);
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'routes')));
//Actually uses the mongodb
//app.use(function(req,res,next){
//req.db = db;
//next();
//});
app.use('/', index);
app.use('/users', users);
app.use('/api', require('./routes/api/appointment/'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
The problem:
res.render('error');
You don't have file error.ejs in views directory
In your directory structure,
views is placed inside of routes directory.
Either you have to place it outside of routes directory or
define views path like this.
app.set('views', path.join(__dirname, 'routes/views'));

Catch all routes loading blank page Angular NodeJs

I was working on Angular app with routing (NodeJs as backend). Routing through pages works fine but when I try to reload page it gives 'cannot load path /home'. I browsed through and got to few solutions like THIS.
My code is
app.get('*', function (req, res) {
res.sendFile('mypath/index.html');
});
But this loads up blank page. Is there any way I can solve this issue?
This us how my server.js looks like
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var port = process.env.PORT || 8080; // set our port
var staticdir = process.env.NODE_ENV === 'production' ? 'dist.prod' : 'dist.dev'; // get static files dir
// get all data/stuff of the body (POST) parameters
app.use(bodyParser.json()); // parse application/json
//app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
//app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form-urlencoded
app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(express.static(__dirname + '/' + staticdir)); // set the static files location /public/img will be /img for users
// routes ==================================================
app.set('views', __dirname + '/app');
app.set('view engine', 'html');
require('./devServer/routes')(app); // configure our routes
// start app ===============================================
app.listen(port); // startup our app at http://localhost:8080
console.log('Starting sever on port ' + port); // shoutout to the user
exports = module.exports = app; // expose app
app.get('/', function (req, res) {
res.render('index', {
page: 'index'
}
});
then out this into your config,
app.set('views', 'directory where index.html is');

Resources