Node.js and expressjs routing to another folder - javascript

I need help with routing using ui.router.
My folder structure looks like this:
In my app.js under javascripts looks like this:
var app = angular.module('testing', ['ui.router']);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html'
})
.state('client_form', {
url: '/request',
templateUrl: '/client.html',
controller: 'MainCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
My index.ejs looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Testing</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="/javascripts/app.js"></script>
</head>
<body ng-app="testing">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</body>
</html>
home.ejs:
<div class="page-header text-center" style="font-size:45px">
Hacker List
</div>
<div class="text-center">
<a href="worker.html">
<button type="submit" class="btn btn-primary btnBig">Worker</button>
</a>
<br />
<a href="Client.html">
<button type="submit" class="btn btn-primary btnBig">Client</button>
</a>
</div>
When I do npm start and go to the website, I get an infinite loop of it not finding home.html.
I can make the code in home.ejs appear if I make it inline inside index.ejs using <script type="text/ng-template" id="/home.html">HOME_CODE_HERE</script>; however, I don't want to do that.
I'm not sure how to fix this.

The ui.router is AngularJS, not NodeJS.
Probably the infinite loop problem is in your front-end, not in NodeJS routes.
Out of the AngularJS problem, I would say that Express routes are in the back-end, so after a request (from Angular, browser, link, redirection etc) the responsibility and configuration needed to work is in NodeJS + Express + EJS.
Let's say you make a request to your /index.html. Once the request gets in the back-end, NodeJS will assume how to handle it.
So, to make sure you don't have a problem in NodeJS, check your app.js (used in node - probably in the root of your project). It could have the routing config similar with this:
var express = require('express');
var app = express();
// EJS template config
app.set('views','./views');
app.set('view engine','ejs');
app.use(bodyParser.urlencoded({ extended: true })); //support x-www-form-urlencoded
app.use(bodyParser.json());
// This is your routes
app.get('/', function(req, res) {
// Your code for index
res.render('views/index', { param : "This is a EJS test" });
});
app.get('/index.html', function(req, res) {
// Your code for index
res.render('views/index', { param : "This is a EJS test" });
});
app.get('/anotherPage.html', function(req, res) {
// Your code for another page: can include validations here
res.render('views/anotherPage', { param : "This is a EJS test" });
});
Now you would have your route set in NodeJS, then you could set your EJS files. Your home.ejs can be exactly the same.
The index.ejs file would be a little different. Maybe you could write it like this (I removed AngularJS from it for testing purposes):
<!DOCTYPE html>
<html>
<head>
<title>Testing</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
This is a parameter from the back-end: <%= param %>
This is the index of EJS template. Below the snipped inserted:
<div class="col-md-6 col-md-offset-3">
<% include home.ejs %>
</div>
</body>
</html>
There are some good examples about routes and EJS in Express github page:
https://github.com/expressjs/express/tree/master/examples
I think that eliminating the problem with NodeJS can help you to fix the problem that seems to be in AngularJS.
Hope it's somehow helpful.

Related

Angular-Route for Templates

I am having trouble getting my routes to work in my Angular application. It is properly displaying the main template, but when I click on the link for the other template, nothing happens. Here's my code:
INDEX.HTML
<!DOCTYPE html>
<html>
<head>
<title>Node, NPM and Bower</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="style.css">
</head>
<body ng-app="app">
<nav>
<h3>Angular App</h3>
Home
About
</nav>
<div ng-view></div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="./app/app.js"></script>
</body>
</html>
APP.JS
angular.module("app", ["ngRoute"]).
config(function($routeProvider) {
$routeProvider
.when("/", {
template : "<h1>Home</h1>"
})
.when("/about", {
template : "<h1>About</h1>"
});
});
Also, is there a reason that Bootstrap and Angular don't work at all when I try to use a localhost with Express and Node? for instance, if I pull up index.html in my browser the text is sans-serif, etc., but if I pull it up using localhost, it's still the default serif font.
SERVER.JS
var express = require('express');
var app = express();
var path = require('path');
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(3000, function() {
console.log('app started');
});
Angular 1.5
So with basic 1.5 routing you need to use:
About
To hit the route. See Plunker for more info
Angular 1.6
If you are using angular 1.6 it's:
About
Look at AngularJS: ngRoute Not Working for other options.
Bootstrap problem
There shouldn't be any problem, it's properly caching.
I figured out the answer. You need to tell the server to route your static files from their directories like so:
app.use(express.static(__dirname + '/views'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.use('/public', express.static(__dirname + '/public'));

MEAN stack - Error while loading AngularJS script

I'm 100% new to MEAN stack and currently trying to self-study it with the help of this video by Michael Moser (If you're reading this, thank you for making such an easy-to-understand video! :) ). I'm trying to make a very basic program with CRUD functionalities, but I can't get past this particular error message when loading the Angular JS file. Can somebody point me in the right direction?
Here are my codes:
package.json
{
"name": "starter-node-angular",
"main": "server.js",
"dependencies": {
"body-parser": "~1.4.2",
"express": "^4.5.1",
"method-override": "~2.0.2",
"mongoose": "~3.8.0"
}
}
server.js
// modules needed
// express - middleware
var express = require('express');
var app = express();
// listens for request to server and throws main.html as response
app.get('/', function(req,res) {
res.sendfile(__dirname + '/client/views/main.html');
});
// listens for request to server with 'scripts' in it and returns the appropriate file declared
// in the script tag
app.use('/scripts', express.static(__dirname + '/client/scripts'));
app.listen(3000, function(){
console.log("Ready...");
});
HTML
<html ng-app="ProductApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.js" type="text/javascript"></script>
<script type="text/javascript" src="/client/scripts/main.js"></script>
<!-- stylesheets -->
<link href="/styles/main.css" rel="stylesheet" type="text/css">
</head>
<body class="main-background" ng-controller="MainController">
<!-- Area for Logo and Search Bar -->
<div class="header">
<div class="main-logo">
STUFF - Product Inventory v1.0
</div>
<div class="main-search">
<input type="text" class="search-field" placeholder="What are you looking for?" />
<img src="images/search-icon.png" title="Search" class="search-ico" />
</div>
</div>
<!-- Area for Add Button -->
<div class="add-container">
<div class="add-button" ng-click="addProduct(test);">
<img src="images/add-icon.png" title="Add" class="add-ico" />
<span class="add-text">Add Product</span>
</div>
</div>
</body>
</html>
AngularJS
'use strict';
var app = angular.module('ProductApp', []);
// Main controller
app.controller('MainController', ['$scope', function ($scope) {
// Search Products
$scope.searchProduct = function (param) {
// Search fxn goes here...
}
// Add products
$scope.addProduct = function (param) {
alert('Add product');
}
// Edit Products
$scope.updateProduct = function (param) {
// Update fxn goes here...
}
// Delete Product
$scope.deleteProduct = function (param) {
// Delete fxn goes here
}
}]);
I came from a background where calling JS files was simply declaring the full path in the src. Tbh, I find the entire MEAN setup a bit complex, with the "middleware" concept and all. :( I appreciate MongoDB's role in it, though.
Anyways, any help and advice would be greatly appreciated. God knows I need a lot of it right now.
Thank you.
Update 1:
I tried changing how my <script> tag calls my angular like so, with no success:
<script type="text/javascript" src="C:/users/myusername/documents/practice/product db/client/scripts/main.js"></script>
Also, am I right in thinking that localhost:3000 refers to Product DB in the following directory structure? I'm aware that 3000 is the port number; after looking at my error logs, I was thinking that localhost is just an alias for the source folder of the app.
Complete path is C:\users\myusername\documents\Practice\Product DB...
Thank you, as always. :)
You have included ng-app in the HTML tag, try adding that in the body of the page.
Do this:
<body class="main-background" ng-app="ProductApp" ng-controller="MainController">
Update:
you have done few mistakes while fetching stylesheets and scripts both. You need to define a proper static route which will work for all the static files(stylesheets and scripts).
you had defined yous static routed like this:
app.use('/scripts', express.static(__dirname + '/client/scripts'));
This will tell the node app to look into client/scripts folder, if any static route starts with /scripts. But you are trying to fetch your script using src="/client/scripts/main.js" which will not get anything, as /client is not defined , nor default '/' route is defined. It should be src="/scripts/main.js" instead.
One more mistake is while fetching stylesheets. you are using href="/styles/main.css", where again neither /styles nor / is defined, thus it will not be able to get the css file.
Try this instead:
Server.js
//define static routes like this
app.use(express.static(__dirname + '/client'));
// this will tell node app to look into the client folder, for any static file
HTML:
Fetch all your files like below:
To get stylesheets :
use /styles/filename
<link href="/styles/main.css" rel="stylesheet" type="text/css">
This will look into styles folder inside client folder.
To get scripts :
use /scripts/filename
<script type="text/javascript" src="/scripts/main.js"></script>
This will look into scripts folder inside client folder.

external Javascript and CSS are not effected to HTML when the HTML is invoked by Node.js

I created a simple Node JS program. I have index.html in the same folder that app.jsis located and external css and js files within public/stylesheets/style.css and /public/javascripts/script.js directories. When i open the index.html directly form the browser, css file is syccessfully linked to the html file. But when i run node app.js and navigate to http://localhost:3000, the index.html is displayed but any style didn't have effected to it. How can i solve it?
app.js file is this
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
server.listen(3000);
app.get('/', function(req, res){
res.sendfile(__dirname + '/index.html');
});
index.html file is this
<html>
<head>
<title>Sanitizor</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="public/javascripts/script.js"></script>
<link rel="stylesheet" type="text/css" href="public/stylesheets/style.css">
</head>
<body>
<h3>hello</h3>
<div id="chat"></div>
<form id="sent-message">
<input size="35" id="message"></input>
<input type="submit"></input>
</form>
</body>
</html>
You need to enable static serving :
app.use(express.static(path.join(__dirname, 'public'))); //this line enables the static serving in the public directory
your public directory could be the following :
public
|_css
|_js
|_images
|_logo.png
Then, if you want to get an image :
http://localhost:3000/images/logo.png
And if you want to show it in your html page :
<img id="logo" src="/images/logo.png"/>
In your case, replace the following line
<script src="public/javascripts/script.js"></script>
by
<script src="/javascripts/script.js"></script>
Same goes with the css
Like Cristy already stated in her comment, you need to enable static serving of your resource files. In order to do so you use express.static. Express has good documentation and guides about routing or middleware etc, so check it out.
Consider a file structure like:
/app
/public/index.html
/stylesheets/style.css
/javascripts/script.js
Your app folder contains the app.js and the rest is ordered like discribed.
Your app.js:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
app.use(express.static(__dirname + '/public'));
var io = require('socket.io').listen(server);
server.listen(3000);
app.get('/', function(req, res){
res.sendfile(__dirname + '/public/index.html');
});
Most of the time the order is important so you need to be carefull. In order to configure express you can use app.configure(function() {...}); and put all you app.use(...) commands in there.
Your index.html now should look like:
<html>
<head>
<title>Sanitizor</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="/javascripts/script.js"></script>
<link rel="stylesheet" type="text/css" href="/stylesheets/style.css">
</head>
<body>
<h3>hello</h3>
<div id="chat"></div>
<form id="sent-message">
<input size="35" id="message"></input>
<input type="submit"></input>
</form>
</body>
</html>

Routing with angular js

My server using angular for routing. My server sending to the browser a HTML file that contains js file with routing (using angular js).
my server code (send to browser check.html contains the routing file main.js) :
var express = require("express");
var app = express(); // express.createServer();
app.use(express.static(__dirname + '/public'));
app.get("/*", function(request, response) {
response.sendFile(__dirname + '/public/check.html');
});
app.listen(8080);
check.html code:
<html data-ng-app="myApp">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="angular-route.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body>
</body>
</html>
after the browser gets the check.html file he doesnt redirect it to main.js in order to use the routing. I tried to debug it but the browser is stuck without doing nothing. my app is local and the url im trying to connect to is:
http://localhost:8080/stations
and all the files are loaded correctly without any errors on the console.
main.js code:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider) {
$routeProvider
.when('/',
{
controller: 'HomeController',
templateUrl: 'menu.html'
})
.when('/stations',
{
controller: 'StationsController',
templateUrl: 'check2.html'
})
.when('/',
{
controller: 'HomeController',
templateUrl: 'menu.html'
})
.otherwise({redirectTo: '/'});
});
myApp.controller('StationsController', function($scope){
$scope.check = {name:"ELAD!!"};
});
check2.html code:
<html>
<head>
</head>
<body>
<div>
<p>{{check.name}}</p>
</div>
</body>
</html>
Ok let's start fresh on angular..
Angular 101
You may know angular is essential for Single Page Application so what happens is you supply the first page that is check.html in your case but you should name it index.html it's a convention. khair.. what happens is when a route transition occurs in the your angular code that is something after # an it's purely client end or a soft redirection. so angular fires an AJAX request to retrieve the resource matching your templateUrl from router. then plugs it inside the <div ng-view></div> thus the redirection. notice the ng-view.
Well bellow is the proposed solution
the link should be http://localhost:8080/#stations as the angular matches handles the routes after #. Other routes like the link you provided are handed to the server.
your check.html should look like this.
<html data-ng-app="myApp">
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="angular-route.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
and your check2.html should be in your public directory and have the code like
<div>
<p>{{check.name}}</p>
</div>

Angular+Node app ignores routing and doesn't load View into ng-view

I am developing a Node+Angular application. I am familiar with Angular, but a beginner in Node so I figured it would be a great start. I am not sure if the problem is with Node or with Angular, so I will just post the code here.
My folder hierarchy is:
- public
- AppAngular
- controllers
chatController.js
- models
- views
chatView.html
app.js
index.html
server.js
In my server.js, I've specified the code below:
app.get('*', function (req, res) {
res.sendFile(__dirname + '/index.html')
})
I don't have any API, since the plan is to build a real-time chat with Socket.io, something I've always wanted to try out.
Anyway, my app.js looks like this:
var app = angular.module('ChatApp', ["ngResource"])
app.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: 'views/chatView.html',
controller: 'chatController'
})
.otherwise({
redirectTo: '/'
})
}])
I have referenced everything in my index.html like this:
<!DOCTYPE html>
<html ng-app="ChatApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Chat</title>
<script src="/node_modules/angular/angular.js"></script>
<script src="/node_modules/angular/angular-resource.js"></script>
<script src="/public/AppAngular/controllers/chatController.js"></script>
<script src="/public/AppAngular/app.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
</head>
<body>
<div ng-view></div>
</body>
</html>
There is no need to post contents of chatView.html and chatController.js since both are straightforward.
Does anyone have the slightest idea to what's the problem? I have a pretty similar config in one of my other projects, with dozens of routes and it works flawlessly but this.

Categories