How to interact with the browser on Node.JS - javascript

I am learning Node.Js, I would like to understand how to interact between front-end / backend.
I would do backend --> Front End interaction by sendig data using app.get(), but now, I'd like to understand how can I get variable from Front End to Backend.
Front-ENd. (I want to pass varGetFromFrontend to backend)
<html>
<script>
var varGetFromFrontend = 2; // This is variable I want to pass to backend
</script>
<head>
<title>Home Page</title>
</head>
<body>
<h1> This is a test</h1>
</body>
</html>
On Node.Js (backend)
var express = require('express');
var app = new express();
app.use(express.json());
app.use(express.static(__dirname + '/public'));
var entries = [
{"id":1, "title":"Hello World!"},
{"id":2, "title":"Hello World!"}
{"id":3, "title":"Hello World!"}
{"id":4, "title":"Hello World!"}
];
if(entries.id == varGetFromFrontend){
console.log("This is to print a variable by choosing it from Front End")
console.log(varGetFromFrontend)
}
var port = Number(process.env.PORT || 5000);
app.listen(port);
I would like to know how can I print "varGetFromFrontend" on server side

Make an HTTP request to the server. Include the variable in the request.
There are lots of ways to do this:
Put it in a hidden input in a form, then submit the form.
or
Set location.href to a new value and include the variable in it (e.g. in a query string)
or
Use the XMLHttpRequest object to make an HTTP request
or
Create a script element and include the variable in the URL for the src attribute
(This is a non-exhaustive list)

You can interact with the nodejs server from the browser with socket.io
First, install socket.io:
npm install socket.io
and write these code to their respective filenames.
app.js:
var express = require("express");
var http = require("http");
var socketIO = require("socket.io");
var app = express();
app.get("/", function(req, res){
res.sendfile("./index.html");
});
var server = http.createServer(app);
var io = socketIO.listen(server, {log: false});
io.sockets.on("connection", function(socket){
socket.on("sendVar", function(value){
console.log("The value of the variable is " + value);
});
});
server.listen(5000);
index.html:
<html>
<head>
<title>Index Page</title>
</head>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var variableFromFrontEnd = 2;
var socket = io.connect("/");
socket.on("connect", function(){
console.log("connected!")
socket.emit("sendVar", variableFromFrontEnd);
});
</script>
</html>
and run it.

Check out the MEAN framework I built: http://mean.wolframcreative.com/
This uses Node as the back-end server utilizing Express as the API router. The front-end uses angular and is purely an api consumption tool.
Short answer is this:
in angular:
$http
.get('/api/users/bobsaget')
.success(function (response) {
console.log(response);
});
in node(with express):
app.get('/api/users/:username', function (req, res) {
var variable = req.params.username;
//do logic here with the database(mongo) to get user info:
db.users.findOne({username: username}, function (error, response) {
if (!error) {
res.send(200, response);
} else {
res.send(500, {success: false, message: error.message});
}
});
)};
Long answer is to play around with my framework and get your hands dirty.

I'm currently working on a restful framework for node call snooze. I'm writing an api along side it and it's going very well. The framework is written to be modular and easy to use. Everything is built around modules, routes, controllers, services, and validators.
https://github.com/iamchairs/snooze
snooze.module('myServer', ['snooze-stdlib']) // inject the snooze-stdlib module
.route('get', '/users/:username', { // define the route
controller: 'UserCtrl', // what controller should handle this route
action: 'getUserByUsername', // what action to perform on this route
validator: 'GetUsername' // before processing this action what validation should occur
})
.controller('UserCtrl', function(User) { // inject the User service
return {
getUserByUsername: function(res, options) {
User.getUserByUsername(options.query.username).then(function(username) {
res.send(200, username);
}).fail(function(err) {
res.send(500, err);
});
}
};
})
.service('User', function($q) { // inject the $q service
return {
getUserByUsername: function() {
var deferred = $q.defer();
deferred.resolve('iamchairs');
return deferred.promise;
}
};
})
.validator('GetUsername', function($validator) { // inject the validator service
return function(deferred, req) {
if($validator.isLength(req.query.username, 2, 32)) {
deferred.resolve(); // resolve (valid request)
} else {
deferred.reject([400, 'Username must be between 2 and 32 characters']); // reject (invalid request)
}
}
});

Related

$http is not working, but request is working in mean stack web app

I have a controller(login.controller.js):
var express = require('express');
var router = express.Router();
var request = require('request');
var config = require('config.json');
router.get('/', function (req, res) {
// log vendor out
delete req.session.token;
// move success message into local variable so it only appears once (single read)
var viewData = { success: req.session.success };
delete req.session.success;
res.render('login', viewData);
});
router.post('/', function (req, res) {
// authenticate using api to maintain clean separation between layers
request.post({
url: config.apiUrl + '/vendors/authenticate',
form: req.body,
json: true
}, function (error, response, body) {
if (error) {
return res.render('login', { error: 'An error occurred' });
}
if (!body.token) {
return res.render('login', { error: body, vendorname: req.body.vendorname });
}
// save JWT token in the session to make it available to the angular app
req.session.token = body.token;
// redirect to returnUrl
var returnUrl = req.query.returnUrl && decodeURIComponent(req.query.returnUrl) || '/';
res.redirect(returnUrl);
});
});
module.exports = router;
Where var request is working accessing Remote REST Api. Where as I have one service(vendor.service.js) which has $http not request. But $http is not working:
(function () {
'use strict';
angular
.module('app')
.factory('VendorService', Service);
function Service($http, $q) {
var service = {};
//Store
service.GetCurrent = GetCurrent;//st_details
return service;
function GetCurrent() {
return $http('http://localhost:3000/api/vendors/st_details').then(handleSuccess, handleError);
}
function handleSuccess(res) {
alert('hi3');
alert(res.data);
return res.data;
}
function handleError(res) {
alert('hi2');
alert(JSON.stringify(res));
return $q.reject(res.data);
}
}
})();
Can I use "var request = require('request');" in this vendor.service.js if yes how? Thanks a million in advance!
It seems like you are not using CORS, which you need to use in order to allow apps to access your API via $http.get
Follow the instructions on https://www.npmjs.com/package/cors to add CORS to your express application and it should work.

Why am I failing to get data from the server using angularjs $http.get()?

The question should be clear enough, and my code should display the issue. Any questions just comment underneath.
app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
var characters = {"Griffins":
[{"Name":"Lois Griffin",
"Gender":"Female",
"Role": "Mother"},
{"Name":"Chris Griffin",
"Gender":"Male",
"Role": "Son"},
{"Name":"Meg Griffin",
"Gender":"Female",
"Role": "Daughter"}]
};
app.get("/characters", function(req, res) {
res.send(characters);
})
app.listen(9000, function(){
console.log('Running');
});
angular.js
app.controller('listCtrl',function($scope, $http){
$scope.characterData = function() {
$http.get("/characters").then(function(data) {
console.log(data, 'success')
},function(data) {
console.log("data, failure.")
})
}
})
error
Failed to load resource: the server responded with a status of 404 (
Object "failure."
object in error
Object -
config : Object
data : "Cannot GET /characters↵"
headers : function (d)
status : 404
statusText : "Not Found"
__proto__ : Object
Note: When using $http.get('characters.json')... I am able to get the data from a file called 'character.json'.
404 is a code which the server sends, when the server is not able to find a resource. There can be many reasons that lead to a 404 in response but the most common one's are:
wrong path given.
spelling problem in the path.
$http.get(url, [config]) : There are 2 arguments that are accepted. url is a absolute/relative path. This is a reason why, $http.get('characters.json') is working instead of $http.get('/characters').
So, you should instead use the proper path. If, 'characters.json' is inside '\characters' directory, you should give the correct path $http.get('\characters\characters.json') so that the server can locate the file.
And also, since you are sending json data, you should use, res.json instead of res.send.
The get method in angular need the full url string, probably is something like this:
app.controller('listCtrl',function($scope, $http){
var serverHost = 'example.com';
var serverPort = '9000';
$scope.characterData = function() {
$http.get("http://'+serverHost+':'+serverPort+'/characters").then(function(data) {
console.log("success");
console.log(data);
},function(data) {
console.log("failure");
console.log(data);
})
}
});
Make characters.json file and change app.get method in app.js
app.get('/characters', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "characters.json", 'utf8', function (err, data) {
data = JSON.parse( data );
console.log( data );
res.end( JSON.stringify(data ));
});
})
//change your server configuration
var server = app.listen(8089, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
You can get Json Data in your html page
My own problem now seems to be working. I don't know what is going on, I think there are stability issues in using an online work space and a virtual machine to run servers, even though there shouldn't be. Thank you for everybody's input, I still managed to pick up some good information.

Express not sending object from Service to API controller

Trying to understand user authentication in order to integrate into my web app. I've been following http://www.sitepoint.com/user-authentication-mean-stack/ as a guide.
I'm a novice when it comes to webdev, so I'm having trouble searching the right thing to fix my problem. The issue is when I try to register a new user my object isn't getting received in my api controller.
register.controller.js
(function () {
angular
.module('misplaced')
.controller('registerCtrl', registerCtrl);
registerCtrl.$inject = ['$location', 'authentication'];
function registerCtrl($location, authentication) {
var vm = this;
vm.onSubmit = function () {
authentication
.register(vm.credentials)
.error(function(err){
alert(err);
})
.then(function(){
$location.path('profile');
});
};
authentication.service.js
(function () {
angular
.module('misplaced')
.service('authentication', authentication);
authentication.$inject = ['$http', '$window'];
function authentication ($http, $window) {
register = function(user) {
return $http.post('/api/register', user).success(function(data){
saveToken(data.token);
});
};
authentication.js
module.exports.register = function(req, res) {
var user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.setPassword(req.body.password);
user.save(function(err) {
var token;
token = user.generateJwt();
res.status(200);
res.json({
"token" : token
});
});
};
Through some console.log I've tracked that the object gets created fine from the register.controller and gets passed to authentication.service fine, but when I try to console.log the object in authentication.js file it's empty. Can someone help explain to me what might be happening? Thanks in advance!
This sounds like an Express configuration issue, you may not be using the bodyParser module in Express.
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
This will allow your middleware to access the request body properties in req.body

Save a JSON file to server in express (node)

Having this function in express that writes a JSON file on a folder
var savingtheJson=function(path, jsonObject, callback){
jsonfile.writeFile(file2, jsonO, callback);
}
I will like to know how can I access/read this file from the browser once is saved.
If I do this:
savingtheJson('/json/myfile.json', jsonObj, function(){
console.log("done it!");
});
When I go to the browser and I type:
http://localhost:8080/json/myfile.json
Of course I get an error from express "Cannot Get ...." cause I think is trying to resolve it like an specific request
How can I store this file into the static folder declared for this goal
(app.use(express.static(__dirname + '/public'))?
How can I access this file once is saved?
First you need to define which folder is going to be exposed as public, so that you can save your json file inside there.
You can use the built-in middleware express.static for this purpose.
Below in the example I have created a endpoint called /users?name=wilson&age=32 which receives query data in order grab user's information as name and age for then you can save it as file named person.json.
So after you consume the above endpoint mentioned, you will be able to consume your file with something like http://localhost:4040/person.json successfully.
var express = require('express');
var app = express();
var port = 4040;
var fs = require('fs');
app.use(express.static('public'));
app.get('/users', function(req, res) {
var name = req.query.name;
var age = req.query.age;
var person = {
name: name,
age: age
};
savePersonToPublicFolder(person, function(err) {
if (err) {
res.status(404).send('User not saved');
return;
}
res.send('User saved');
});
});
function savePersonToPublicFolder(person, callback) {
fs.writeFile('./public/person.json', JSON.stringify(person), callback);
}
app.listen(port, function() {
console.log('server up and running at port: %s', port);
});

How to make ajax get/post request in express server?

Below is my express server. I am trying to make a get request in ajax, but it turned out failed even though I required jquery at the beginning. It said $ is not defined Other than using jquery ajax, what else can I use to make an API call form RESTful API url?
var express = require('express');
var requestHandler = require('./requestHandler');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname, '../client')));
app.get('/homepage', requestHandler.getData);
var port = process.env.PORT || 3000;
app.listen(port);
console.log("Server running at: http://localhost:" + port);
// request handler file:
var express = require('express');
var url = "http://jsonplaceholder.typicode.com/";
module.exports.getData = function (req, res){
$.ajax({
method: 'GET',
url: url+'posts',
success: function(data) {
console.log(data);
res.send(data);
}
});
}
module.exports.getComments = function(userId){
$.ajax({
method: 'GET',
url: url+'/comments',
success: function(data) {
console.log(data);
}
});
}
HTTP GET Request in Node.js Express
var http = require('http');
var options = {
host: 'www.google.com',
path: '/index.html'
};
var req = http.get(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
// Buffer the body entirely for processing as a whole.
var bodyChunks = [];
res.on('data', function(chunk) {
// You can process streamed parts here...
bodyChunks.push(chunk);
}).on('end', function() {
var body = Buffer.concat(bodyChunks);
console.log('BODY: ' + body);
// ...and/or process the entire body here.
})
});
req.on('error', function(e) {
console.log('ERROR: ' + e.message);
});
You need to understand things like:
expressjs is serverside code so it can't use jquery ajax like that.
jQuery.ajax() can only be used at view when you load your page in the browser.
You need to use some view engines like jade to create templates and use routers to push the view in the browser. When you have your view in the browser then you can make a reference to the script file which can contain your ajax code to let you have posts and comments.
More information.
Try something like this:
function() {
// Simple POST request example (passing data) :
$http.post("/createProject/"+ id +"", {
projectTitle: pTitle,
userID : id
}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
$scope.getProjects();
console.log("project created");
console.log("this is the response data " + data);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
};
Also please note. you will call this from an external JavaScript file. One the express server you will only have "routes" and from external javascript files you can perform HTTP calls on those routes.
Update
#Someone, the express framework is very popular to setup a web server in Node. You can use different render engines to render the view and pass information to the user. This is a very simple example from the Express website listening to two urls (/posts and /comments).
var express = require('express');
var app = express();
app.get('/posts', function (req, res) {
res.send('Render posts!');
});
app.get('/comments', function (req, res) {
res.send('Render comments');
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});

Categories