I have a Node.JS+Express backend, and am trying to set up an angular frontend.
I have a basic HTML template called common.html:
<!DOCTYPE HTML>
<html>
<head>
<title>Watson-Amadeus</title>
<link rel = "stylesheet" href = "css/index.css" />
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel = "script" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.min.js"></script>
<script src="js/amadeus.js"></script>
</head>
<body ng-app = "watson_amadeus">
<div ui-view>
</div>
</body>
</html>
js/amadeus.js then looks like
var app = angular.module("watson_amadeus", ["ui.router"]);
app.config(($stateProvider) => {
var introState = {
name: "intro",
url: "/intro",
templateUrl: "../index.html"
}
var amadeusState = {
name: "amadeus",
url: "/amadeus",
template: "../watson-amadeus.html"
}
$stateProvider.state(introState);
$stateProvider.state(amadeusState);
});
app.controller("amadeus_controller", ($scope) => {
$scope.messages = [
{text: "Yo"},
{text: "sup?"}
];
console.log("controller");
$scope.send_message = () => {
$scope.messages.push({text: $scope.msg_to_send});
$scope.msg_to_send = "";
};
});
intro.html and watson-amadeus.html are then just partials with some html in them. My Node server code looks like this:
var express = require('express'),
amadeus = require('./rest/amadeus.js'),
body_parser = require('body-parser');
var app = express();
app.use(body_parser.json());
app.use(body_parser.urlencoded({extended: false}));
app.use(express.static("public")); // Use static pages from the public directory
app.post("/api/amadeus/", amadeus.send_message);
app.get("*", (req, res) => {
res.sendFile(__dirname + "/public/common.html");
});
app.listen(8080); // Set the server to listen on port 8080
Finally, my directory structure is reasonably straightforward:
project_dir
public
js
amadeus.js
common.html
index.html
watson-amadeus.html
node_server.js
package.json
When I start the web server and try http://localhost:8080/intro, I am greeted with just a blank screen, and looking at the page source shows that it is just loading common.html without putting the index.html content into the viewport as it should. What is more; when I do http://localhost:8080/, I get the contents of index.html, but without the parts from common.html.
I'm new to angular, so this may be something fundamental but I don't know where I have messed up.
Once you defined app.use(express.static('public'));, express server will load index.html automatically, so app.get("*", (req, res) => { res.sendFile(__dirname + "/public/common.html"); }); won't run at all.
I would recommend rename common.html to index.html since it is your major html.
By default ui-route will add#! to url, try http://10.8.8.8:8080/, after index.html has been loaded successfully, the url actually changed to http://10.8.8.8:8080/#!/.
Hence, you can access your /intro by http://10.8.8.8:8080/#!/intro.
There will be lots of effort to take if you want to remove #!, you can research next step. Good luck!
Related
So I am creating a new module with a single controller, saved in controllers directory off of the app directory:
var tables = angular.module('tables',[]).controller('setName', function ($scope) {
$scope.userName = userName;
$scope.userPassword = userPassword;
});
I have the following html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ang</title>
</head>
<script src="/socket.io-client/socket.io.js"></script>
<script src="/angular/angular.min.js"></script>
<body ng-app="tables">
<div ng-controller="setName">
User Name: <input type="text" ng-model="userName" ><br>
Password: <input type="text" ng-model="userPassword" ><br><br>
User Name: {{userName}}<br>
Password: {{userPassword}}<br>
</div>
</body>
</html>
I am using express to serve the page:
//Load express
var express = require('express');
//Load tables
//var tables = angular.module('table');
// Create express app
var app = express();
//Load http express wrapper
var http= require('http');
//Create variable for the port the server listens on
var srvPort = 3000;
//Make a static path to node_modules directory
app.use(express.static('node_modules'));
app.use(express.static('controllers'));
//Make a static path to the public directory
app.use(express.static('public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
var server = http.createServer(app).listen(srvPort, function () {
console.log('Server is listening on port ' + srvPort);
});
require('./public/javascript/sockets.js').initialize(server);
I get the following error:
Failed to instantiate module tables due to:
Error: [$injector:nomod] http://errors.angularjs.org/1.5.0/$injector/nomod? p0=tables
at Error (native)
at http://localhost:3000/angular/angular.min.js:6:416
at http://localhost:3000/angular/angular.min.js:25:136
at b (http://localhost:3000/angular/angular.min.js:24:188)
at http://localhost:3000/angular/angular.min.js:24:431
at http://localhost:3000/angular/angular.min.js:39:287
at n (http://localhost:3000/angular/angular.min.js:7:355)
at g (http://localhost:3000/angular/angular.min.js:39:135)
at fb (http://localhost:3000/angular/angular.min.js:43:164)
at Ac.c (http://localhost:3000/angular/angular.min.js:20:449
So my question is, why is my module not loading?
Any help would be appreciated!
Z
You're not loading it in <head>. You have only socket.io.js and angular.min.js but not the JS file containing your module.
I am having trouble setting up ng-view. This is my first mean stack app. I got everything working within index.html. However, when I set up ng-view I am getting errors stating that I have my javascripts in a public folder. My index.html is in the html folder. I have set up an additional folder in views called templates to house my additional pages
"GET http://localhost:3000/templates/home.html 500 (Internal Server Error)"
Inside of my html I have set up ng-view
<!doctype html>
<html lang="en" ng-app='myApp'>
<head>
<meta charset="UTF-8">
<title>Caffeine app</title>
<!-- styles -->
<link href="http://netdna.bootstrapcdn.com/bootswatch/3.3.2/yeti/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="stylesheets/style.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="container>
<div ng-view>
</div>
</div>
<!-- scripts -->
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-route/angular-route.min.js"></script>
<script src="javascripts/main2.js" type="text/javascript"></script>
</body>
</html>
In my public js folder I have set up my factory, config, and controllers. I am using swig.
var app = angular.module('myApp', ['ngRoute'], function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when('/home',{
templateUrl:'templates/home.html',
controller:'myController'
})
.when('/drinkLibrary',{
templateUrl:'templates/drinkLibrary.html',
controller:'DrinkLibraryController'
})
.otherwise({
redirectTo: '/home'
})
$locationProvider.hashPrefix('!');
});
app.factory('Drink',function($http) {
var Drink = function(name,description,caffeineLevel) {
this.name = name;
this.description = description;
this.caffeineLevel = caffeineLevel;
}
return Drink;
})
app.controller('HomeController',function($scope){
console.log('home');
})
app.controller('DrinkLibraryController',function($scope){
console.log('drinkLibrary');
})
app.controller('myController', function($scope,Drink,$http ) {
var init = function() {
$scope.defaultForm = {
beverageName: "",
description: "",
caffeine: ""
};
}
init();
// $scope.defaultForm = defaultForm;
$scope.allDrinkList = [];
$scope.drinkList= function(obj) {
var newdrink = new Drink(obj.beverageName,obj.description,obj.caffeine);
$scope.allDrinkList.push(newdrink);
console.log($scope.allDrinkList);
init();
$http.post('/api/drinks',obj).
success(function(data){
console.log(data)
$scope.message = 'success';
}).
error(function(data){
console.log('error');
})
};
});
Inside of my routes folder I am making sure to render the index
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
In doing a mean stack I must remember to set up routes on the server and client side. My templates are in the view. I am rendering my view through express I need to also render my templates in the same manner.
app.use('templates/:templateid', routes);
I am using the express generator so through the routes I called a get request and set the url to the templates folder. Next, I identified the template id as a param. This saves me from setting up each page ex(home,library, about).
router.get('/templates/:templateid' ,function(req,res,next){
res.render('templates/' + req.params.templateid);
})
I have started working an app using angularjs which can have have different UI themes.
index.html
<html lang="en" data-ng-app="appConfigurator">
<head>
<title>The title</title>
</head>
<body data-ng-controller="appCtrl">
<div data-ng-view></div>
</body>
<script type="text/javascript" src="libs/angular.js"></script>
<script type="text/javascript" src="libs/angular-route.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/services/webservice.js"></script>
<script type="text/javascript" src="js/controllers/appCtrl.js"></script>
<script type="text/javascript" src="js/router.js"></script>
</html>
app.js - Here I initialize my module and also declare a global variable 'theme'.
var appConfigurator = angular.module("appConfigurator", ['ngRoute']);
var theme = "";
webservice.js - This service make Web service calls to the backend and gets the data as response.
appConfigurator.factory('webService', function($http) {
return {
callService : function(method, fileType, rowId, data, message, type) {
return $http({
method : method,
url : url,
data : "Message=" + message + "&XMLData=" + data + "&Type=" + type,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
}
});
}
};
});
appCtrl.js - This is the main app controller. Here I am making a webservice call to get the data and then using this data I will have to make one more call to get the name of the "theme" I need to use. So basically two calls.
appConfigurator.controller("appCtrl", function($scope, webService) {
$scope.succ = function(res) {
//alert("success" + res.name);
};
$scope.err = function(res) {
alert("error");
}
webService.callService('POST', 'data', 'ID', '', 'Message','XML').success($scope.succ).error($scope.err);
});
router.js - Based on the value of theme the route will route to the particular folder structure which will contain the theme specific HTML, CSS and JS files.
appConfigurator.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/Config', {
templateUrl: 'themes/'+theme+'/views/a.tmpl.html',
controller: ''
}).otherwise({
redirectTo: '/Config'
});
}
]);
The obvious problem is that by the time routers sets the path for the tempelateUrl I don't have the name of the theme.
Solutions -
1) One solution (this one works) is to get the theme name in the URL as a parameter but that cannot be done on the backend side. So there is no point of this solution.
2) Is there a way I can delay the routing process so that by the time angular tries to route I have the theme name.
The development is in very initial stage. Comments to change the approach will also be helpful. And yes Angularjs is all new to me and my peers.
appConfigurator.config(['$routeProvider', function($routeProvider) {
// set theme name
var theme = 'theme_name';
$routeProvider.when('/Config', {
templateUrl: 'themes/'+theme+'/views/a.tmpl.html',
controller: ''
}).otherwise({
redirectTo: '/Config'
});
}
]);
Im trying to create a simple application using backbone..
When i am trying to run my code,this error shows
Failed to load resource: the server responded with a status of 404
(Not Found) users.
What this program really does is, just call the router.js file and render a simple html..
Please help me to clear the error..
If i use ajax prefilter then no errors and also no output.
Im using eclipse and tomcat server7.
And also my important question is
How to use a RESTful Api in a Backbone program and give me a sample
program?
Here is my code..
My HTML code:
<html>
<head>
<meta charset="utf-8">
<title>Welcome Backbone</title>
</head>
<body>
<div class="container">
<h1>User Manager</h1>
</div>
<div class="page"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"
type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"
type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"
type="text/javascript"></script>
<script type="text/javascript" src="js/router.js"></script>
</body>
</html>
My js code:
/**
* New node file
*/
/* $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
options.url='http://localhost:8080/PageProject/#'+options.url;
console.log(options.url);
}); */
var Users = Backbone.Collection.extend({
url: '/users'
});
var UserList = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var users1 = new Users();
users1.fetch({
success: function () {
that.$el.html('!CONTENT SHOULD BE HERE');
console.log('request reached');
}
});
}
});
var Router = Backbone.Router.extend({
routes: {
'': 'home'
}
});
var UserList = new UserList();
var router = new Router();
router.on('route:home', function () {
console.log('Welcome Backbone!');
UserList.render();
});
Backbone.history.start();
I'm building a modular javascript application (RequireJS/Backbone), and am looking for some advice on best practices for propagating server-side URLs into the JS application for use in client side templating, API requests, etc.
Inject it into the base template that kicks off the Javascript application?
API request specifically for this purpose?
Would love to hear solutions others have used. Thanks!
You can render a <script> tag in the body, define a module and put your URLs there in any way you like.
After that you can require it inside your modules (.js files).
HTML (e.g. your application layout):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inline RequireJS define</title>
</head>
<body>
<h1 id="foo-holder"></h1>
<a id="sign-up-link" href="#"></a>
<script>
// This is rendered by your server-side application:
define('data/config', function(require, exports, module) {
exports.Url = {
HOME: 'https://mysite.com',
SIGN_IN: 'https://mysite.com/sign-in',
SIGN_UP: 'https://mysite.com/sign-up',
LOG_OUT: 'https://mysite.com/log-out'
};
exports.foo = 'bar';
});
</script>
</body>
</html>
JavaScript (somewhere in your module):
// This is somewhere in your JavaScript module
require(['data/config'], function(Config) {
$('#foo-holder').text(Config.foo);
$('#sign-up-link')
.text(Config.Url.SIGN_UP)
.attr('href', Config.Url.SIGN_UP);
});
DEMO
Another trick could be done with some kind of attribute-binding.
In your layout:
<a data-url="HOME" href="#">Home</a>
<a data-url="SIGN_IN" href="#">Sign In</a>
<a data-url="SIGN_UP" href="#">Sign Up</a>
<a data-url="LOG_OUT" href="#">Log Out</a>
<script>
// This is rendered by your server-side application:
define('data/config', function(require, exports, module) {
exports.Url = {
HOME: 'https://mysite.com',
SIGN_IN: 'https://mysite.com/sign-in',
SIGN_UP: 'https://mysite.com/sign-up',
LOG_OUT: 'https://mysite.com/log-out'
};
exports.foo = 'bar';
});
</script>
In your JavaScript file:
// This is somewhere in your JavaScript module
require(['data/config'], function(Config) {
$('a[data-url]').each(function() {
var $a,
urlConstant,
url;
$a = $(this);
urlConstant = $a.data('url');
url = Config.Url[urlConstant];
if(url) {
$a.attr('href', url);
}
});
});
DEMO