Redirect with Node.js and angular - javascript

I am having trouble trying to redirect POST requests using Node.js, Express and angular. I am aware there is a standard way of using forms as follows:
index.ejs
<!DOCTYPE html>
<html>
<head>
<title>Redirect Example</title>
</head>
<body>
<p>INDEX PAGE</p>
<form action="/redirect" method="post">
<button type="submit">CLICK</button>
</form>
</body>
</html>
test.ejs
<!DOCTYPE html>
<html>
<head>
<title>Redirect Example</title>
</head>
<body>
<p>YAY REDIRECTED</p>
</body>
</html>
app.js
var fs = require('fs');
var https = require('https');
var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var app = express();
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.render('index');
});
app.post('/redirect', function(req, res){
res.redirect('/test');
});
app.get('/test', function(req, res) {
res.render('test');
});
var port = process.env.PORT || 1337;
app.listen(port, function(){
console.log('http://localhost:' + port + '/');
});
This method automatically redirects the page to the "test" route since it uses a form to handle the post request.
However using when I use an angular approach, the page does not automatically redirect. How would I do this?
index.ejs
<!DOCTYPE html>
<html ng-app="project">
<head>
<title>Redirect Example</title>
<script src="/javascripts/jquery/jquery.js"></script>
<script src="/javascripts/angular/angular.js"></script>
<script src="/javascripts/angular/angular-route.js"></script>
<script src="/javascripts/main.js"></script>
</head>
<body ng-controller="MainController">
<button type="submit" ng-click="submit()">CLICK</button>
</body>
</html>
main.js
var app = angular.module('project', []);
app.controller('MainController', ['$scope', '$http', function ($scope, $http) {
$scope.submit = function() {
$http.post('/redirect');
}
}]);

Try keeping the redirection from within Angular, as Angular is meant to stay client-side in its own module. Like I said in a comment, you can send a status code from the server indicating the client to do a redirect.
For example, change your express endpoint to something like
app.post('/redirect', function(req, res){
res.status(300).send({ redirect:"/test"});
});
And your Angular Controller to something like
var app = angular.module('project', []);
app.controller('MainController', ['$scope', '$http', '$window', function ($scope, $http, $window) {
$scope.submit = function() {
$http.post('/redirect').then(function(data, status){
$window.location.href = data.redirect;
});
}
}]);
This way you can specify the redirect address from within server-side code.
Edit: In addition, I think you would need a hashtag for your redirect in angular, unless you have HTML5 mode enabled.

Routes created by node.js server are actual routes while AngularJS routing is based on hash (#) tags like -
Routes in node.js -
app.get('/myroute') will be like - http://localhost:8000/myroute
Routes in AngularJS -
'/myangroute' will be like - http://localhost:8000/#/myangroute
So coming back to your question, $http.post('/redirect'); is not redirecting you but posting the data to '/redirect' route(defined at server end). For redirection use angularjs $location service.

Related

How to avoid socket id change with socket.io?

I'm currently trying to make a support application (like, to live chat with support) and I'm looking for a way to avoid the change of the socket id.
Here is my index.js code:
const app = require('express')();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);
io.on('connection', function (socket) {
socket.on("hello",()=>{
socket.emit("hello",socket.id)
})
})
app.get("/",(req,res)=>{
res.sendFile(__dirname+"/client/index.html")
})
server.listen(1002)
And here is my client/index.html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Socket.io</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<p id="socketid"></p>
<script>
const socket = io();
socket.emit("hello")
socket.on('hello',(message)=>{
document.getElementById("socketid").innerHTML=message;
})
</script>
</body>
</html>
Thanks in advance for your help!
I think you cannot make socketid constant. Every time you reconnect or connect a new socket id will be given to you. Actually why do you want to make socketid constant?

Submit value from HTML form to Node-js

I want to submit input value from HTML form to Node-js. Node-js should assign that value as an argument to a Solidity function. But the Error: TypeError: Cannot read property 'oinput' of undefined is shown. What should i do? Please help a beginner.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Alireza</title>
<body>
<form id="FORM" name="FORM" method="POST" action="http://127.0.0.1:1408">
<input id="Finput" name="oinput" value="Null" onclick="this.form.submit()"/>
</form>
<script>
document.forms[0].oinput.value=prompt("Type a thing: ","Here ...");
</script>
</body>
</html>
app.js:
var express=require('express');
var app=express();
var fs=require('fs');
var http = require('http');
var bodyParser=require('body-parser');
var Web3=require('web3');
var web3=new Web3('ws://127.0.0.1:8545');
var YerevanJSON="E:/Alireza/build/contracts/Yerevan.json";
var YerevanJS=JSON.parse(fs.readFileSync(YerevanJSON));
var YerevanABI=YerevanJS.abi;
var Yerevan=new web3.eth.Contract(YerevanABI, "0x1E6B6524e7da86bafa5ac948b38dA68e6841f0c7");
Yerevan.defaultAccount="0x152AfF6BBF98F2FF2EFAdA32E2ba85CC231cbA13";
app.post("/", function(q,r){
Yerevan.methods.eval(q.body.oinput).send({from:"0x33aa0ba26Dc247BA5d94545344c413949B746360"});
});
app.listen(1408, err=>{ console.log('ERROR')});
Solidity:
pragma solidity ^0.5.12;
contract Yerevan{
string public city;
function eval(string memory sense) public returns(string memory){
city=sense;
return city;
}
}
You have included body-parser on to the file but hasn't asked the app use it.
add below line
const bodyParser = require("body-parser");
// for parsing application/json
app.use(bodyParser.json());
//for parsing application/xwww-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
You are using var, start using const and let instead.

AngularJS Webpage Can't Find Referenced Angular Module or Controller

Sorry for the possible repost, but I don't know how else to write this. I've been using this website to create a small angularJS webpage using nodeJS as well, and I've gotten to the part of separating the angular code from the view, or HTML. What I've found was that when I tried to separate them nothing worked any more.
Here's my code so far:
Home.html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<!-- <script>
var myApp = angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myColor = "red";
});
</script> -->
</head>
<body>
<!-- <script>
myApp.directive('myDirective', function() {
return {
template: "This is a test directive."
};
})
</script> -->
<h2>myApp Test</h2>
<div ng-app="myApp" ng-controller="myCtrl" ng-init="quantity = 10; cost = 5">
<p>Color: <input type="text" style="background-color:{{myColor}}" ng-model="myColor" value="{{myColor}}"></p>
<p>Total in dollar (raw exp): {{quantity * cost}}</p>
<p>Total in dollar (span): <span ng-bind="quantity * cost"></span></p>
<p> First Name: <input type="text" ng-model="firstName"></p>
<p> Last Name: <input type="text" ng-model="lastName"></p>
<h1>Hello, {{firstName + " " + lastName}}</h1>
</div>
Are you even changing?!
</body>
<script type="javascript" src="../JS/myApp.js"></script>
<!-- <script type="javascript" src="../JS/myApp.module.js"></script> -->
<script type="javascript" src="../JS/myCtrl.js"></script>
<!-- <script type="javascript" src="../JS/myCtrl.component.js"></script> -->
</html>
myApp.js / myApp.module.js:
var myApp = angular.module('myApp', []);
myCtrl.js / myCtrl.component.js:
myApp.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myColor = "red";
});
// app.directive('myDirective', function() {
// return {
// template: '<p><h3>This is a test directive.<h3></p>'
// };
// });
Finally, here's my folder hierarchy:
If what I've done wrong is already evident, there's no need for you to continue reading.
Now the commented-out code is important as well. These are both the other things I've tried, and what I wanted to implement. I have tried:
Re-adding all the angular code back to the head tag to make sure it was still working at all. It worked, aside from the directive stuff (which, at point, I believe would have to be part of a separate module, but not the point, nonetheless).
Moving the script references, which are, and were, located below the body, to the head.
Moving the script references to the top of the body.
Moving everything into just *one* file (myApp.module.js).
Renaming both "myCtrl.component.js" and "myApp.module.js" to "myCtrl.js" and "myApp.js", respectively, to ensure possibly-antiquated angularJS nomenclature wasn't an attribution.
Adding "type="javascript"" to the script references.
"Hard refreshing" to make sure old documents weren't cached.
Tested to see if it was even requesting the files from the server using node. It doesn't look like it is.
If you need the nodeJS part of it, it's here as well (index.js):
var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var myUrl = url.parse(req.url);
var basename = path.basename(myUrl.path);
console.log('request url: ' + req.url);
console.log('url path: ' + myUrl.path);
console.log('basename: ' + basename);
fs.readFile('../HTML/Home.html', function(err, data) {
res.writeHead(200, { 'ContentType': 'text/html' });
res.write(data);
res.end();
});
}).listen(8080);
The problem is in your script tag
<script type="javascript" src="../JS/myCtrl.js"></script>
It should not be
type="javascript"
Either change it to
type="text/javascript"
or remove the type totally. Due to incorrect type , it is not loading controller and other js files to browser.

Update part of HTML page using NODE.JS and EJS

I have the following express app which just renders the sample.ejs page. On that page when I press the button the attached script changes the div text to
"THIS IS FROM J QUERY. I want the same thing to happen but I want the data to be coming from a database. In my express app if I try to use res.render(); every time I click the button then it reloads the page which I don't want. So is there a way to achieve this without reloading page and only update part of page?
I have searched stack overflow and the web but can't get an appropriate answer or maybe I just am unable to understand. I know this is a very basic thing to ask.
APP.js
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(express.static('./src/views'));
app.set('views', './src/views');
app.set('view engine' , 'ejs');
app.listen(3000 , (err)=>{console.log('Listening')});
app.get('/' , function(req , res) {
res.render('sample' , {result_from_database: res.body} );
});
sample.ejs
<!doctype html>
<html lang="en">
<head>
<title>Sample HTML File</title>
</head>
<body>
<div id="holder">
WELCOME
</div>
<form>
<button type="button" id="HButton"> HELLO </button>
</form>
</body>
<script>
$(document).ready(function () {
var form = $("#holder");
$("#HButton").on("click", function () {
form.html("THIS IS FROM J QUERY");
});
});
</script>
<script src="/lib/jquery/dist/jquery.js"></script>
</html>
Now this is what I want to do
<!doctype html>
<html lang="en">
<head>
<title>Sample HTML File</title>
</head>
<body>
<div id="holder">
<%= result_from_database %>
</div>
<form>
<button type="button" id="HButton"> HELLO </button>
</form>
</body>
<script>
$(document).ready(function () {
var my_div = $("#holder");
$("#HButton").on("click", function () {
/* Tell app.js that I clicked a button and then app.js
query the database and using ejs or something else update the
my_div inner html with the database result without
reloading page */
});
});
</script>
<script src="/lib/jquery/dist/jquery.js"></script>
</html>
NOTE: I'm not asking how to query the database
-Thanks
You have to define and endpoint in your back end that return the information you want to display:
app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(express.static('./src/views'));
app.set('views', './src/views');
app.set('view engine' , 'ejs');
app.listen(3000 , (err)=>{console.log('Listening')});
app.get('/' , function(req , res) {
res.render('sample' , {result_from_database: res.body} );
});
app.get('/api/books', function(req, res) {
res.json({
message: 'Your database information'
});
});
then on your front end you need to make a call to api endpoint like:
sample.ejs
<script>
$(document).ready(function () {
var my_div = $("#holder");
$("#HButton").on("click", function () {
$.ajax({
url: "/api/books"
})
.done(function( data ) {
console.log( "Sample of data:", data );
$('#holder').html(data.message);
});
});
});
</script>
You can find more information on ajax call with jquery here.
However i would suggest you to use any framework like angular or react to make it easier to render the data in your html, otherwise you will have to write a lot of code using jquery.

node.js: How can I output a variable directly to index.html

How can I get the user inputs from index.html, process in node and output the result back into the index.html? Instead of outputting - as currently does - to a new page.
Form file
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/', function(req, res){
res.sendFile('index.html', { root: __dirname});
app.post('/mess', function(req, res){ //means same dir
var userNum1 = req.body.num1;
var userNum2 = req.body.num1;
var answer = parseInt (userNum1) + parseInt (userNum2);
res.send ('The answer is ' + answer);
});
app.listen(80);
index.html
<!DOCTYPE html>
<html>
<head>
<title>Forms></title>
</head>
<body>
<form action="mess" method="post">
<p>Enter a number:</p>
<input type="text" name="num1" placeholder="..." />
<br>
<p>Enter a number:</p>
<input type="text" name="num2" placeholder="..." />
<br>
<button type="submit">Submit</button>
<br>
</form>
</body>
</html>
Probably the easiest way is to use ejs.
First npm install ejs. Then add this to your Express app code:
app.set('view engine', 'ejs');
// this allows you to render .html files as templates in addition to .ejs
app.engine('html', require('ejs').renderFile);
In your route handler you just do something like:
res.render('form', { answer: 'foo' });
and then your template (e.g. ./views/form.html) would look like:
<html>
<p> The answer is <%= answer %> </p>
</html>
An alternative to the EJS is to use socket.io. You can attach an event handler to each entry, or to the submit button and then use socket.io to send it from client to server, process it and have it sent back. Then you page can update on receiving the data from the server.

Categories