Nodejs Connection to HTML - sql-server

I am Getting an HTML ERROR, Trying to render a sql db to the index page with setting up a connection. The table name is employee and no error while running the app on the terminal but an error page on the html link.
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
GetData(function (recordSet) {
res.render('index', {product: recordSet})
console.log(recordSet);
});
});
function GetData(callBack){
var sql = require('mssql');
var Config = {
user: 'Gurpanth\\Gurpanth',
password: '',
database:'NodeJSDb',
server:'GURPANTH'
};
var conn = new sql.ConnectionPool(Config,function (err) {
//If any error
var request = new sql.Request(conn);
request.query('Select * from products', function(err, recordSet){
callBack(recordSet);
});
});
}
module.exports = router;
INDEX.EJS
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<table>
<tbody>
<td><%=productName%></td>
</tbody>
</table>
</body>
</html>

You are passing the variable product: res.render('index', {product: recordSet})
but in the ejs file you are using productName <td><%=productName%></td>
Change both to the same

Related

How to load controller using angular 1 and simple server?

When I run this server, ā€œ/ā€œ will run index.html, but index.html cannot reach controller.js in order to populate the 'item' variables using data.json.
However, when I copy controller.js as a script inside index.html, the item variables are populated with the data.json contents.
In both cases, index.html cannot access the css and image files, even though the right path is supplied.
How can index.html access a seperate controller.js as well as the other files without error? Why is this happening? Iā€™m trying to do this without express first, if it's possible. Any ideas would be appreciated.
JS/CONTROLLER.JS
var myApp = angular.module("myApp", []);
myApp.controller("MyController", function MyController($scope, $http) {
$http.get('/api').success(function(data) {
$scope.artists = data;
})
})
INDEX.HTML
<!doctype html>
<html leng="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>My AngularJS App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="js/controller.js"></script>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h2> Welcome {{name}} </h2>
<div ng-controller = "MyController">
<ul class="artistlist">
<li class="artist cf" ng-repeat="item in artists">
<img ng-src="public/images/{{item.shortname}}_tn.jpg" alt="photo of {{item.name}}">
<div class = "info">
<h2> {{item.name}} </h2>
<h2> {{item.reknown}}</h2>
</div>
</li>
</ul>
</div>
</div>
</body>
</html>
DATA.JSON
[
{
"name":"Barot Bellingham",
"shortname":"Barot_Bellingham",
"reknown":"Royal Academy of Painting and Sculpture"
},
{
"name":"Jonathan G. Ferrar II",
"shortname":"Jonathan_Ferrar",
"reknown":"Artist to Watch in 2012"
} ā€¦ ]
SERVER.JS
var http = require('http');
var url = require("url");
var fs = require("fs");
var path = require('path');
var server = http.createServer(handleRequest);
var PORT = 3000;
server.listen (PORT, function() {
console.log("listening on ", PORT)
})
function handleRequest(req, res) {
var urlParts = url.parse(req.url);
switch (urlParts.pathname) {
case "/":
index(urlParts.pathname, req, res);
break;
case "/api":
api(urlParts.pathname, req, res);
break;
default:
display404(urlParts.pathname, req, res);
}
}
function index(url, req, res){
fs.readFile("./index.html", "UTF-8", function(err, html) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(html);
});
}
function api(url, req, res) {
fs.readFile("./data.json", "utf8", function(err, data) {
res.writeHead(200, {"Content-Type": "text/json"});
res.end(data)
});
}
function display404(url, req, res) {
res.writeHead(404, {
"Content-Type": "text/html"
});
res.write("<h1>404 Not Found </h1>");
res.end("The page you were looking for: " + url + " can not be found ");
}
One way of loading two files; however, how would this flow if each file were of a different content-type (one html, and the other js)? from: LINK
function css(response) {
response.writeHead(200, {"Content-Type": "text/css"});
var count = 0;
var handler = function(error, content){
count++;
if (error){
console.log(error);
}
else{
response.write(content);
}
if (count == 2) {
response.end();
}
}
fs.readFile('css/bootstrap.css', handler);
fs.readFile('css/bootstrap-responsive.css', handler);
}

Angular JS Templating

i have a template set for all my view pages which i load using
app.route('/*').get(core.renderIndex);
where and the renderIndex function looks like
exports.renderIndex = function (req, res) {
res.render('modules/core/server/views/index', {
user: req.user || null
});
};
Now when my route has announcement in it i render a different template and not index.server.view.html
app.route('/:shopId/:locationId/announcement/*').get(core.renderAnnouncement);
exports.renderAnnouncement = function (req, res) {
res.render('modules/core/server/views/announcement', {
user: req.user || null,
});
};
The reason why i'am doing this is because i need to change the meta tags over this page i.e. i need to set variables on view before the page renders which comes from another controller.
My question is how can i access variables in a server.view.html file?
<!DOCTYPE html>
<html lang="en" ng-controller="OfferController" ng-init="getAnnouncement()">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
<base href="/">
<title>{{ gettitle }}</title>
like the gettitle which is setting from getAnnouncement method of OfferController.
This works if i set a different announcement.client.view.html file and in the server file extend it
In case someone is stuck and needs help here is how i did this
app.get('/:shopId/:locationId/announcement/*',function(req,res,next){
async.waterfall([
function (done) {
var resultsObj = '';
var httpTransport = 'http://';
if (config.secure && config.secure.ssl === true) {
httpTransport = 'https://';
}
var url = httpTransport + req.headers.host+'/api/offer/getbyid/'+req.params[0];
request.get(url, function (err, res, body) {
resultsObj = JSON.parse(body);
done(err, resultsObj);
});
},
function (resultsObj, done) {
var httpTransport = 'http://';
if (config.secure && config.secure.ssl === true) {
httpTransport = 'https://';
}
var url = httpTransport + req.headers.host+'/api/shops/'+req.params.shopId+'/'+req.params.locationId;
request.get(url, function (err, res, body) {
var resultsObjNew='';
resultsObjNew = JSON.parse(body);
done(err, resultsObjNew,resultsObj);
});
},
function (resultsObjNew,resultsObj, done) {
res.render('modules/core/server/views/announcement', {
title: resultsObj[0].title,
imageUrl : resultsObj[0].imageURL,
desc : resultsObj[0].desc,
link:resultsObj[0].redirectLink,
logoLink: resultsObjNew.logoLink,
backgroundImage:resultsObjNew.backgroundImage
});
}
]);
});
where
var request = require('request');
var async = require('async');
var path = require('path');

Error: [ngRepeat:dupes] Using MEAN w/ Heroku

I'm simply fetching data from a database and displaying it in an html file with ngRepeat. Connection to database is successful and I'm able to add data to it. Also everything on the client side works as I'm able to display data in the ngRepeat div with a defined array. So the problem must be somewhere in the .get() method but I can't figure out what it is. Any suggestions?
server.js
var express = require('express');
var mongojs = require('mongojs');
var MongoClient = require("mongodb").MongoClient;
var app = express();
var port = process.env.PORT || 3000;
var db = mongojs('heroku_1x6kasdf');
var plantList = db.collection("plantList");
app.use(express.static(__dirname + "/"));
MongoClient.connect(process.env.MONGOLAB_URI, function(err, db) {
if (err) throw err;
console.log('SUCCESS! Connected to heroku_1x6kasdf database');
app.get("/", function(req, res) {
plantList
.find({})
.toArray(function(err, docs) {
if (err) throw err;
res.json(docs);
});
});
});
app.listen(port, function() {
console.log('SUCCESS! Connected to ' + port);
});
controller.js
var myApp= angular.module('myApp', []);
myApp.controller('AppCtrl', ['$scope', '$http', function($scope, $http) {
var refresh = function() {
$http.get("/").success(function (response) {
$scope.plantList = response;
});
};
refresh();
}]);
index.html
<html ng-app="myApp">
...
<div ng-controller="AppCtrl">
<div ng-repeat="plant in plantList">
<p>{{plant.name}}</p>
<p>{{plant.variety}}</p>
<p>{{plant.quantity}}</p>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="controllers/controller.js"></script>
</body>
</html>
track by the plant id. I would not recommend track by $index as it tracks by position rather than item, which will cause problems down the line.
<div ng-controller="AppCtrl">
<div ng-repeat="plant in plantList track by plant.id">
<p>{{plant.name}}</p>
<p>{{plant.variety}}</p>
<p>{{plant.quantity}}</p>
</div>
</div>
This error occur when an object is found twice in an array. when you don't specify "Track by" in a repeater, angular track it by the special property "$$hashKey" which usually is something like: "object:76", "object:77" etc.
You can console.log your array and then check if one of the object has the same $$hashKey

Uncaught SyntaxError: Unexpected token < angular.1-2-13.min.js:1

I am new in angular jS and while.I am using node server to deploy my application locally.Bit facing this error in chrome browser.
PFB my code
Demo.html
<html ng-app="Demo">
<head>
<script type="text/javascript" src="lib/angular.1-2-13.min.js"></script>
<script type="text/javascript" src="lib/angular-route.1-2-13.min.js"> </script>
</head>
<body ng-controller="DemoController">
USA<input type='radio' name='txt1' ng-model="value" ng- change="changeValue(value)" value="USA"> Non-USA<input type='radio' name='txt1' ng-model="value" ng-change="changeValue(value)" value="NUSA">
<select ng-model="selectedItem" ng-options='option.name for option in optionValues'>
</select>
<input type='text' name='txt1' ng-model='txtValue'/>
<input type='button' name='b1' ng-click='takeValue(txtValue)'/>
routing
<div ng-view></div>
<script type="text/javascript">
var demo = angular.module( "Demo", ['ngRoute'] );
demo.config(['$routeProvider','$locationProvider', function ($routeProvider,$locationProvider) {
$routeProvider
// Pages
.when("/about", {templateUrl: "/Users/smundhe/Desktop/NewProject/Demo2.html",controller: "Demo2Controller"})
// else 404
.otherwise("/404", {templateUrl: "partials/404.html",controller: "PageCtrl"});
//$locationProvider.html5Mode(true);
}]);
demo.controller(
"DemoController",
function( $scope ) {
$scope.optionValues=[{name:'1'},{name:'2'},{name:'3'}, {name:'4'}];
$scope.takeValue = function(txtValue){
alert(txtValue);
}
$scope.changeValue=function(value){
alert(value);
if(value=="USA"){
$scope.optionValues=[{name:'1'},{name:'2'}, {name:'3'},{name:'4'}];
}
else if(value=="NUSA"){
$scope.optionValues=[{name:'A'},{name:'B'}, {name:'C'},{name:'D'}];
}
}
});
demo.controller(
"Demo2Controller",
function( $scope ) {
$scope.optionValues=[{name:'1'},{name:'2'},{name:'3'},{name:'4'}];
alert('hiii');
});
</script>
server.js
// set our port
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var port = 3000;
app.use(bodyParser.json());
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(methodOverride('X-HTTP-Method-Override'));
app.get('/*', function(req,res)
{
console.log('sending file: ' + req.url);
res.sendfile(__dirname + '/Demo.html');
});
app.listen(port);
Can some one help me on this?
Thanks in advance..
Your problem is in this line:
app.get('/*', function(req,res)
{
console.log('sending file: ' + req.url);
res.sendfile(__dirname + '/Demo.html');
});
This is basically saying that for any incoming GET request, always send back Demo.html. As a result, when your page's <script> tag requests the angular.min.js, it is given Demo.html, which the browser then tries to run as a javascript file, throwing the "unexpected <" error.
Instead, what you should do is something like the following:
var serveStatic = require('serve-static');
app.use(serveStatic(__dirname, {'index': ['Demo.html']}))
This will essentially serve whatever file is requested, and if no file is requested (i.e. /, then will return Demo.html).
Note you will need to npm install --save serve-static.
See the serve-static docs for more info.

AngularJS - Templates not working

I am using Restangular to create a simple API using MEAN stack.
Here is my code:
index.html
<!DOCTYPE html>
<html data-ng-app="scotchTodo">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->
<title>Node/Angular Todo App</title>
<!-- SCROLLS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"><!-- load bootstrap -->
<style>
html{
overflow-y:scroll;
}
body{
padding-top:50px;
}
</style>
<!-- SPELLS -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-route.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/restangular/1.4.0/restangular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div data-ng-view>
</div>
</body>
</html>
app.js
var scotchTodo = angular.module('scotchTodo', ['restangular','ngRoute']);
//config
scotchTodo.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/',{
templateUrl: 'list.html',
controller: 'ListController'
})
.when('api/todos/:todo_id',{
templateUrl: 'edit.html',
controller: 'EditController'
});
$locationProvider.html5Mode(true);
}]);
//controllers
scotchTodo.controller('ListController', ['$scope', 'Restangular',
function($scope, Restangular) {
//GET ALL
var baseTodo = Restangular.all('api/todos');
baseTodo.getList().then(function(todos) {
$scope.todos = todos;
});
//POST -> Save new
$scope.save = function() {
var baseTodo = Restangular.all('api/todos');
var newTodo = {'text': $scope.text};
baseTodo.post(newTodo).then(function(todos) {
$scope.todos = todos;
$scope.text = '';
});
};
//DELETE
$scope.delete = function(id) {
var baseTodo = Restangular.one('api/todos', id);
baseTodo.remove().then(function(todos) {
$scope.todos = todos;
});
};
}]);
scotchTodo.controller('EditController', ['$scope', 'Restangular','$routeParams',
function($scope, Restangular, $routeParams) {
var baseTodo = Restangular.one('api/todos', id);
baseTodo.getList().then(function(todo) {
$scope.todo = todo[0];
window.test = "dev";
});
//PUT -> Edit
$scope.update = function(id){
var baseTodo = Restangular.one('api/todos', id);
baseTodo.text = "Edited";
baseTodo.put().then(function(todos) {
$scope.todos = todos;
});
};
}]);
list.html
<div>
<div data-ng-repeat="todo in todos">
{{todo.text}}Edit<button data-ng-click="delete(todo._id)">X</button>
</div>
<input type="text" data-ng-model="text"/>
<button data-ng-click="save()">Add</button>
</div>
edit.html
<div>
<input type="text" data-ng-model="text" value="{{todo.text}}" />
<button data-ng-click="update(todo._id)">Save</button>
</div>
server.js
// setup ========================
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
//configuration =================
mongoose.connect('mongodb://127.0.0.1:27017/sl', function(err, db) {
if (!err) {
console.log("We are connected to " + db);
}
});
app.use(express.static(__dirname + '/public'));
app.use(bodyParser());
// application -------------------------------------------------------------
app.get('/', function(req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
//listen ========================
app.listen(8080);
console.log('App started on the port 8080');
//define model ==================
var Todo = mongoose.model('Todo', {
text: String
});
// routes ======================================================================
// api ---------------------------------------------------------------------
//get one todo
app.get('/api/todos/:todo_id', function(req, res) {
// use mongoose to get all todos in the database
Todo.find({
_id: req.params.todo_id
},function(err, todos) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err){
res.send(err);
}
res.json(todos); // return all todos in JSON format
});
});
// get all todos
app.get('/api/todos', function(req, res) {
// use mongoose to get all todos in the database
Todo.find(function(err, todos) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err){
res.send(err);
}
res.json(todos); // return all todos in JSON format
});
});
// create todo and send back all todos after creation
app.post('/api/todos', function(req, res) {
// create a todo, information comes from AJAX request from Angular
Todo.create({
text: req.body.text,
done: false
}, function(err, todo) {
if (err){
res.send(err);
}
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err);
res.json(todos);
});
});
});
// update todo and send back all todos after creation
app.put('/api/todos/:todo_id', function(req, res) {
// create a todo, information comes from AJAX request from Angular
Todo.update({
_id: req.params.todo_id
}, {
text:req.body.text
}, function(err, todo) {
if (err){
res.send(err);
}
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err);
res.json(todos);
});
});
});
// delete a todo
app.delete('/api/todos/:todo_id', function(req, res) {
Todo.remove({
_id: req.params.todo_id
}, function(err, todo) {
if (err){
res.send(err);
}
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err){
res.send(err);
}
res.json(todos);
});
});
});
The first page of my app loads perfectly fine. Here is the screenshot.
But when I click on either of the edit link it is supposed to load edit.html template. But it shows a blank page with no errors in console. Here is the screenshot.
I am unable to figure out what's wrong. Please help. Please ask if any other piece of code is needed. I added almost everything that I did. I know it is annoying and not recommended but I am not sure what part of my code is causing this issue.
EDIT 1:
My farthest guess is that the url for edit.html might not be getting resolved correctly. But I am not sure how to test that! Any help will be appriciated.
EDIT 2: Directory structure
SOLUTION : Courtesy #ashu
The issue was this line in index.html
<script src="app.js"></script>
It should be:
<script src="/app.js"></script>
However, I am not clear why! Page was including app.js either way. It is weird.
You have same routes for angular and express.
.when('api/todos/:todo_id',{
templateUrl: 'edit.html',
controller: 'EditController'
});
and in express
app.get('/api/todos/:todo_id', function(req, res) {
Hence, there is ambiguity. You can remove the 'api' part from angular urls.
.when('/todos/:todo_id', {
templateUrl: 'edit.html',
controller: 'EditController'
})
And in server, you can add a catchall route which will handle all the non-api urls. For doing that you can move your app.get('/', function(req,res) {..}) call at the bottom after defining your api routes.
// < Define APi Routes here >
//catch all route for serving the html template
app.get('/*', function(req, res ) {
res.sendfile('./public/index.html')
});
Also, in your app.js EditController, you forgot to initialise value of id.
var id = $routeParams.todo_id;

Resources