execute server side script for file creations - node.js

Using node.js, I am developing a small web application where want to create a file on server with a button click on browser. I have a small file "file.js" in public folder as below,
var fs = require("fs");
console.log("Going to write into existing file");
fs.writeFile('input.txt', 'Simply Easy Learning!', function(err) {
if (err) {
return console.error(err);
}
console.log("Data written successfully! checked");
console.log("Let's read newly written data");
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("Asynchronous read: " + data.toString());
});
});
It works fine when i execute this as "node file.js" and creates a input.txt. Calling this file in html page where trying to call through ajax call as below,
<!DOCTYPE html>
<html>
<head>
<meta content="en-us" http-equiv="Content-Language">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
console.log(' firstpage ');
function readTextFile(){
console.log(' in function readTextFile ');
var dataString;
$.ajax({
type: "GET",
url: "file.js",
data: dataString,
success: function(err,data){
alert( "Data Saved: " + data );
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
</script>
</head>
<body>
<p class="auto-style1"><strong>Welcome to MyPage</strong></p>
<div >
<input class="myButton" type="button" onclick="readTextFile()" value="Submit" />
</div>
</body>
</html>
Pressing the button gives me error,
ReferenceError: require is not defined
at eval (eval at <anonymous> (jquery.min.js:2), <anonymous>:1:10)
at eval (<anonymous>)
at jquery.min.js:2
at Function.globalEval (jquery.min.js:2)
at text script (jquery.min.js:4)
at Pc (jquery.min.js:4)
at x (jquery.min.js:4)
at XMLHttpRequest.b (jquery.min.js:4)
please help , where i am making mistake and how to fix. Many thanks in advance.

A couple things to help you understand what's going wrong:
1) Running "node file.js" is executing your JavaScript file on your server in a node.js environment.
2) When you run your webpage and fetch and execute file.js, your browser is running file.js using its own JavaScript interpreter directly in the browser.
3) node.js has additional features for server side applications, one being the "require" syntax. This allows server side applications to include other JavaScript files rather than loading them in some HTML with a script src tag
4) node.js also provides some modules that are particularly useful for server side applications, such as "fs"
Your file.js looks like it's coded specifically to be run on the server side rather than on a browser client. It uses node.js syntax and even manipulates a file on the file system
You will need to run a node.js server (express.js being one popular choice) that can execute your file.js via some API endpoint. Then change your browser code to call the endpoint instead of trying to fetch and execute file.js directly in the browser

Related

Ejs doesn't load when I call a function from another file

Basicly I want to run a function when I clicked the button, but it works when I started the server and go to localhost one time, here's what's supposed to happen, after that localhost page doesn't load. (Unable to connect error)
If I remove the function there is no problem. How can I get it to work only when I click the button ?
Many thanks.
My func.js
const mongoose = require("mongoose");
const axios = require('axios');
async function func() {
//MyCodes
}
module.exports = {
func: func
}
My index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button type="button" onClick= <%= func.func() %> >Click</button>
//Other codes are independent the button
</body>
</html>
My res.render codeblocks in app.js
var func = require('./func');
app.get("/", (req, res) => {
res.render('index', {
cName: name,
symbol: symbol,
len: finds[0].result.length,
cPrice: price,
cDate: date,
func:func
});
});
});
})
You are misunderstanding. You cannot call an internal nodejs function(backend) from the html (frontend). If your frontend need to execute some backend operation like query to mongo, you have these options:
#1 client side rendering (Modern)
This is the most used in the modern world: Ajax & Api
your backend exposes a rest endpoints like /products/search who recieve a json and return another json
this endpoints should be consumed with javascript on some js file of your frontend:
html
<html lang="en">
<head>
<script src="./controller.js"></script>
</head>
<body>
<button type="button" onClick="search();" >Click</button>
</body>
</html>
controller.js
function search(){
$.ajax({
url:"./api/products/search",
type:"POST",
data:JSON.stringify(fooObject),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(response){
...
}
})
}
Note 1: controller.js contains javascript for browser not for backend : nodejs
Note 2: ejs is only used to return the the initial html, so it is better to use another frameworks like:react, angular, vue
#2 server side rendering (Legacies)
In this case, ajax and js for browser are not strictly required.
Any event on your html should use <form> to trigger an entire page reload
You backend receives any parameter from the , make some operations like mongo queries and returns html instead json, using res.render in your case
Note
Ejs is for SSR = server side rendering, so add ajax could be complex for novices. In this case, use the option #2
You cannot use a nodejs function (javascript for server) in the client side (javascript for browser). Maybe some workaround are able to do that but, don't mix different things.

Uncaught reference error require is not defined

I'm trying to use an html page in order to test the connection with my server.
I've got no problem with my server.js
var http = require('http');
var url = require("url");
// Chargement de socket.io
var io = require('socket.io').listen(server);
var server = http.createServer(function(req, res) {
var page = url.parse(req.url).pathname;
// Quand un client se connecte, on le note dans la console
});
io.sockets.on('connection', function (socket) {
console.log('Un client est connecté !');
});
server.listen(8080);
My client should is an html page here
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.io</title>
</head>
<body>
<h1>Communication test with socket.io !</h1>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://localhost:8000/server_node/node_modules/socket.io/lib/socket.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
</script>
</body>
</html>
Problem is, when I load the html client, I've got this error
socket.js:6 Uncaught ReferenceError: require is not defined
at socket.js:6
I'm not trying to implement a real client, I just want a simple page in order to do some connection test.
Thanks for your help
EDIT: Problem fixed, it was all because I wasn't loading the html file from the serverlike this fs.readFile('./ClientTest.html', 'utf-8', function(error, content) {
As this is just used to do some test, it's fine if it works this way; the client side will be with an other platform.
Sorry for that useless issue :(
You appear to be importing the server-side library on the client, you want to be importing the client-side one.
As per the docs, this is automatically served when socket.io runs on the server which you can import via
<script src="/socket.io/socket.io.js" />

Accessing server side functions using Express.js and EJS

I'm running a test app in Express.js using EJS as the templating engine. I'd like to access functions stored in a .js file to run server side and not client side. For instance if I have:
<%= console.log("I'm in the server console"); %>
the server catches the console output, and if I have:
<script type="text/javascript"> console.log("I'm in the client-side console"); </script>
Now if I have a function to output the same for the client side I can include it this way:
<script type="text/javascript" src="/javascripts/clientSideCode.js"> clientSideOutput(); </script>
But how do I include a file and its functions that way so EJS can execute server side code? It appears that the public folder in express is just for client side code.
You can create helper functions that your templates can access via app.locals:
http://expressjs.com/api.html#app.locals
You can use node.js and Socket.IO to emit real time events between client and server. For instance the client would do something like:
<script>window onload = function() {
socket.emit('request_customer_list', { state: "tx" });
socket.on('receive_customer_list', function(data) {
$.each(data.customer_list, function(key, value) {
socket.set(key, value); // store the customer data and then print it later
});
});}
On your server you can have a routine to load the customer list and send it back in similar format:
socket.on('connection')
socket.on('request_customer_list', function(data){
state = data.state;
var customer_list;
// pretend i loaded a list of customers from whatever source right here
socket.emit('receive_customer_list', {customer_list: customer_list});
)} )};

now.js - Hello World example - "require not defined"

I'm having trouble getting the now.js chat client tutorial to work. (I've also followed this video almost exactly).
server.coffee:
fs = require 'fs'
http = require 'http'
now = require 'now'
server = http.createServer (req, res) ->
fs.readFile(
'index.html'
(err, data) ->
res.writeHead(
200
'Content-Type': 'text/html'
)
res.end(data)
)
server.listen 8080
everyone = now.initialize(server)
everyone.now.distributeMessage = (msg) ->
everyone.now.receiveMessage(#.now.name, msg)
index.html:
<html>
<head>
<title>nowjs title</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/Flotype/now/master/lib/now.js"></script>
<script type="text/javascript">
$(document).ready(function() {
now.name = prompt("What's your name?", "");
now.receiveMessage = function(name, msg) {
return $("<div></div>").text("" + name + ": " + msg).appendTo("#msg");
};
return $("#send-button").click(function() {
now.distributeMessage($("#text-input").val());
return $("#text-input").val("");
});
});
</script>
</head>
<body>
<div id="msg"></div>
<input type="text" id="text-input">
<input type="button" value="Send" id="send-button">
</body>
</html>
When I load up the server with node server.js,
I get an error that says "require not defined" on line 1 of now.js. Consequently, the client side code can't find the variable 'now'.
I understand that 'require' is a node function, but how do I get the client to understand that?
Any help will be appreciated.
The file you're including in your client source (../Flotype/now/master/lib/now.js) is the Node server side code that is included in your node process when calling now = require 'now'.
So changing your included client source file from .../Flotype/now/master/lib/now.js to /nowjs/now.js will fix your problem.
Where does this /nowjs/now.js file come from?
When using NowJS (and many other npm packages that do client/server communication) you extend the server object. This is done with the line everyone = now.initialize(server) (Code Here).
What the initialize function does is wrap your server with the fileServer (Code Here) class in NowJS. This adds a resource under the "folder" nowjs which serves the client now.js file.
I got this error when trying to run nodejs file with js command instead of node.
Eg: if the nodejs file name is test.js, I was doing
js test.js
instead of
node test.js
I hope this helps too for people searching for this error.

Consuming a Stream create using Node.JS

I have an application, which streams an MP3 using Node.JS. Currently this is done through the following post route...
app.post('/item/listen',routes.streamFile)
...
exports.streamFile = function(req, res){
console.log("The name is "+ req.param('name'))
playlistProvider.streamFile(res, req.param('name'))
}
...
PlaylistProvider.prototype.streamFile = function(res, filename){
res.contentType("audio/mpeg3");
var readstream = gfs.createReadStream(filename, {
"content_type": "audio/mpeg3",
"metadata":{
"author": "Jackie"
},
"chunk_size": 1024*4 });
console.log("!")
readstream.pipe(res);
}
Is there anyone that can help me read this on the client side? I would like to use either JPlayer or HTML5, but am open to other options.
So the real problem here was, we are "requesting a file" so this would be better as a GET request. In order to accomplish this, I used the express "RESTful" syntax '/item/listen/:name'. This then allows you to use the JPlayer the way specified in the links provided by the previous poster.
I'm assuming you didn't bother visiting their site because had you done so, you would have seen several examples of how to achieve this using HTML5/JPlayer. The following is a bare-bones example provided by their online developer's documentation:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery.jplayer.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#jquery_jplayer_1").jPlayer({
ready: function() {
$(this).jPlayer("setMedia", {
mp3: "http://www.jplayer.org/audio/mp3/Miaow-snip-Stirring-of-a-fool.mp3"
}).jPlayer("play");
var click = document.ontouchstart === undefined ? 'click' : 'touchstart';
var kickoff = function () {
$("#jquery_jplayer_1").jPlayer("play");
document.documentElement.removeEventListener(click, kickoff, true);
};
document.documentElement.addEventListener(click, kickoff, true);
},
loop: true,
swfPath: "/js"
});
});
</script>
</head>
<body>
<div id="jquery_jplayer_1"></div>
</body>
</html>

Resources