how to resolve ExpressJS routing when using AngularJS html5Mode (back4app/Parse-Server) - javascript

I'm using back4app BaaS service that uses Parse-Server. For the ClientSide I'm running AngularJS with html5Mode(true);
My problem is that this is NOT working: http://app.rizop.tv/dashboard
While this is working right: http://app.rizop.tv
Any idea how to fix expressJS to handle my routes in the right way?
I have this config:
cloud\app.js
// Helper modules that will be used
var path = require('path');
var bodyParser = require('body-parser')
// This imports the Router that uses the template engine
var index = require('./routers/index');
// Sets the template engine as EJS
app.set('view engine', 'ejs');
// This defines that the 'views' folder contains the templates
app.set('views', path.join(__dirname, '/views'));
// These options are necessary to
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// This bind the Router to the / route
app.use('/', index)
// Starts listening in the routes
app.listen();
cloud\routers\index.js
// Importing express
var express = require('express');
// Creating a Router
var route = express.Router();
// Defining a route that binds the GET method
route.get('/', function(req, res) {
// This is the code that renders the template
res.render('index', {testParam: 'Back4Apper'});
});
module.exports = route;
cloud\views\index.ejs
<!doctype html>
<html>
<head>
<meta charset="utf-8">
...
</body>
...
</body>
</html>
Here is my app structure:

You can make it work by making little changes in app.js and root html file
I assume you already defined $locationProvider.html5Mode(true); where you defined your routes. Then define base href in your index html
<head>
<base href="/">
...
</head>
This answer might be helpful to configure your server

The file at cloud/app.js should not have app.listen() on its final line, due to the fact that you are using Cloud Code. Can you please try that?

I have ran into the same problem and did the following
I've put this route as the last option, so when the express router ran out of options it will render the index file where is the angular app. Angular internal router will resolve that route and draw the view.
router.get('*', function (req, res) {
res.render('index', {testParam: 'Back4Apper'});
});
Obviously you can write a smarter regex instead of * according to your needs but you get the idea.

Related

Error: Module "html" does not provide a view engine (Express)

I'm trying to set up a simple routing app but I keep running int the error when rendering a page.
Error: Module "html" does not provide a view engine.
What is odd is I've specified the view engine in my app.js file but I'm still getting the error
// app.js
var express = require('express');
var app = express();
var router = express.Router();
// Need to import the route file
var chef = require('./chef');
app.use('/chef', chef);
// Set directory to contain the templates ('views')
app.set('views', __dirname + '/views');
// Set view engine to use
app.set('view engine', 'html');
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// chef.js
var express = require('express');
var routes = express.Router();
routes.get('/', (req, res) => {
//res.send("I'm here!")
res.render('chef');
});
module.exports = routes;
// views/chef.html
Some HTML file here here ..
In the chef.js file when I just want to test if the route is working I uncomment res.send ... which sends "I'm here" to the DOM.
However whenever I try res.render to render the chef.html page I get the error above. Which I find odd because I've set the view engine in app.js.
Suggestions on how to render my HTML file?
use res.sendFile('/fileName.html'); instead of res.render()
for sending file , we used res.sendFile(fullPath) and if you are using other than HTML language then you should have to use res.render().
res.render() for template like ejs, pug etc.

ui route, node, express, 404 html files

I can't figure this out for the life of me. I'm using Node, Express, Angular and ui.route. What I'm trying to accomplish is the following,
have index.html as a master
have some.html as partials
I setup the application to use ejs instead of jade (don't know if that matters at all)?
The error I'm getting is that it can't find localhost:3000/views/partial-home.html 404, I tried all types of different paths in my routing,
(function(){
var app = angular.module('routerApp', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/about');
$stateProvider
.state('home-about', {
url: '/home-about',
templateUrl: '/views/partial-home.html'
})
.state('about', {
});
});
}());
I do not have anything particular in my app.js file to handle html or in my route/index.js, currently I think it's using the index.ejs as well. What steps am I missing in using html and why could the error be with it not finding the partial-home.html
//routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
There are posts about this topic but none kinda sums up my two issues with using html files and why the 404. Appreciate all help I can get. Thanks!
You still need to 'mount' this router to the app.
app.use('/', router);
The router will be relative to the path that you mount it to, in this case the root /. You can mount it to any path and the router will be relative to that path. e.g.
app.use('/bar', router);
And your router 'mini-app' will be invoked when the application gets (or any other HTTP method) /bar/ path.
Hey you can set your app view engine as html such that it can render html file.
var ejs=require("ejs");
app.set('views',//folder path of views);
app.engine('html', ejs.renderFile);
app.set('view engine', 'html');
I got the solution. It's just one of those gotchas. I was looking into my app.js, I had all the routing correct as Arbel was helping me with.
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
So I was looking though the file and it hit me when I seen this line, right that this is a static resource.
app.use(express.static(path.join(__dirname, 'public')));
So I put my html files into public/partials and that was it.
Now my route look like this
$stateProvider
.state('home-about', {
url: '/home-about',
templateUrl: '/partials/partial-home.html'
});

how to get locals in Express from routes

I have a variable defined as local on my app.js file like this (app is really express) :
app.locals.weather = { /* unimportant content here */ };
Now, I want to access that information from my index.js route to print on a ejs template. I'm trying this, but it says it is undefined:
var express = require('express');
var router = express.Router();
console.log(express.locals);
What is the right way to do that?
The documentation states:
You can access local variables in templates rendered within the application.
In other words, you don't have to do anything special to pass weather to your EJS template, by assigning it to app.locals you make it available through your app.
All keys created under app.locals are available directly to the template.
In your template you should not refer to it as locals.weather, instead try only weather
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.set('views', __dirname + '/templates');
app.locals.weather = 'hot';
app.get('/', function(req, res){
console.log('received req');
res.render('hello');
});
app.listen(3000)
And the ejs template
<!DOCTYPE html>
<div>
hello ejs
</div>
<div>
<%= weather %>
</div>
And it works

javascript not loading using express static

first let me explain that i am not expecting myself to submit this as i had referred and experimented repeatedly on countless attempts but still i could not get the javascript and images served via expressjs. The project folders structure:
[root] (the project folder)
|server.js <-- the main file
|[staticFiles] (contains js img files)
|[html] (contains html files)
|[js] (contains javascripts)
|[node_modules] (library home)
server.js: (the main file)
var express = require('lib/express');
var app = express();
var port = process.env.PORT || 65000;
var bodyParser = require('./node_modules/body-parser');
var router = express.Router();
var cons = require('consolidate');
var path = require('path');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', "./html");
app.use('/user1', require('./js/routes/user1'));
// here i'd tried various combinations:
var staticPathFinal = express.static(path.join(__dirname, 'staticFiles'));
app.use(staticPathFinal);
// app.use(express.static(path.join(__dirname, 'staticFiles')));
// app.use(express.static(__dirname, 'staticFiles'));
// app.use(express.static(__dirname + '/staticFiles'));
// app.use(express.static(__dirname + '/staticFiles/')); // 2123
// app.use(express.static('staticFiles')); // 2159
// app.use('/user', express.static('staticFiles'));
// app.use('/user', express.static(path.join(__dirname, 'staticFiles')));
app.listen(port);
[user1: ./js/routes/user1]
[js]
|routes
|user1.js
code:
router.get('/', function(req, resp) {
resp.render("srcEvent1");
}
[html: srcEvent.html] with basics removed for easy reading:
<head lang="en">
<title>srcEvent.html</title>
<script src="srcEvent.js"></script>
</head>
<body onload="srcEvent_alert()">
<h1>page info: this shall activate alert from srcEvent.js:</h1>
</body>
[staticFiles] (folder containing javascript & img)
srcEvent.js
function srcEvent_alert(){
alert('srcEvent_alert:0006:');
}
on server run ok expects connection.
on browser url [localhost:65000/user1]
result1: without <script src="srcEvent.js"></script> page loaded :-)
result2: with <script src="srcEvent.js"></script> page could not load :-(((
that made me spent many stressful countless hours crossed project timeline over days experimenting wrt answers from stackoverflow and elsewhere but simply mine did not work though the setup seemed to conform to those googled references.
someone please help me out of that dungeon.
thanks.
daniel
Probably you are using relative path (without slash) <script src="srcEvent.js"> so it tries to find js at /staticFiles/user/srcEvent.js Try to change it to <script src="/srcEvent.js"> and see if it works.
Also I would recommend you to use developer tools inside the browser and see which url exactly it tries to load (from network panel)
P.S. You can use require('express') instead of require('./node_modules/express/lib/express') because node itself looks for the dependencies inside node_modules folders

How to set path to partials in Node.js with Express, Handlebars and Conslidate

I have a working Node.js site, using Express.js, Handlebars.js and Consolidate.js. I want to use partials for common parts of my templates, but can't work out how to make them work for pages at different URLs.
My /views/ directory contains this:
_footer.html
_header.html
article.html
index.html
The relevant parts of my Node app looks something like:
var express = require('express'),
consolidate = require('consolidate'),
handlebars = require('handlebars'),
path = require('path');
var app = express();
app.engine('html', consolidate.handlebars);
app.set('view engine', 'html');
app.set('views', path.join(__dirname, '/views'));
var partials = {header: '_header', footer: '_footer'};
app.get('/', function(req, res) {
res.render('index', {partials: partials});
};
app.get(/^\/([\w-]+)\/$/, function(req, res) {
res.render('article', {partials: partials});
};
And in my index.html and article.html Handlebars templates I have something like:
{{> header}}
<!-- page content here -->
{{> footer }}
I should be able to access both / (when index.html is rendered) and /foo/ (when article.html is rendered). But it only works for whichever I try to access first after starting the Node server. When I then navigate to the other path, I get errors like:
Error: ENOENT, no such file or directory '/Users/phil/Projects/projectname/views/<!DOCTYPE html>...
with the rest of the _header.html partial following.
I assume I need to somehow set the path to my partials to be absolute somehow, but I can't see how to do that.
For consolidate check that : https://github.com/tj/consolidate.js/issues/18
I would recommend to switch to something a bit more specific like that https://github.com/donpark/hbs it will be simpler.
I had the same exact issue. It seems that consolidate is reusing the "partials" object that you pass, replacing the values with the file content (yuck!).
A workaround is to create a new "partials" object every time. If you don't want to rewrite the whole object every time, you can use a function returning the object literal.
In your case something like the following should work:
var express = require('express'),
consolidate = require('consolidate'),
handlebars = require('handlebars'),
path = require('path');
var app = express();
app.engine('html', consolidate.handlebars);
app.set('view engine', 'html');
app.set('views', path.join(__dirname, '/views'));
var partials = function() {
return {header: '_header', footer: '_footer'};
}
app.get('/', function(req, res) {
res.render('index', {partials: partials()});
};
app.get(/^\/([\w-]+)\/$/, function(req, res) {
res.render('article', {partials: partials()});
};
Not really elegant, but I don't think there is really a way to keep it simpler.

Categories