Javascript/node link main.js - javascript

So I am just learning and I am trying to build a web app using node, I know I could use express but I am trying to build it all using Node to get a better understanding.
The problem is I cant get the main.js page to load on the app.
I have a router module that builds the page eg
function home(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(fs.readFileSync('./views/header.html'));
res.write('<style>' + fs.readFileSync('./css/styles.css') + '</style>');
res.write(fs.readFileSync('./views/startpage.html'));
res.end(fs.readFileSync('./views/footer.html'));
};
and the script tag is in the footer partial just before the closing body tag, would i need to load it a different way ?
Here is the full app if this is not enough information, thanks
https://github.com/naassi/taxi-log

You probably want a static file server for all your css and javascript files. Instead of sending the CSS file content in home, include
<style>./css/styles.css</style>, and answer the request for *.css files with the appropriate file:
function staticServer(req, res) {
fs.readFile(__dirname + req.url, function (err,data) {
if (err) {
res.writeHead(404);
res.end(JSON.stringify(err));
return;
}
res.writeHead(200);
res.end(data);
});
})
In footer, you want to load a .js file - your Node server is responsible for serving that, just like it handles a request for e.g., home.
If you're learning Node, try to stay away fron Sync functions, they block the event loop, and defeat Node's good parts :)

Related

How to Unit test HTML output from node?

This might be a dumb question: I have an .html file with one <script> (main.js) initially loaded on it, which programmatically add structure on that html file. Also this script adds another which uses that structure to draw some charts.
Then, I am serving this html with node. Also I am serving those scripts in my server.js like this:
app.get('/', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile('./index.html', 'utf8', function(error, data) {
if (error) {
res.writeHead(404);
res.write('File not found!');
} else {
res.write(data);
}
res.end();
});
});
app.get('/main.js', function(req, res) {
res.sendFile(path.join(__dirname + '/..' + '/main.js'));
});
And so...
Everything is working great. User can't have interaction with the page, so everything will remain the same .
Now, I want to develop some unit tests on that .html (like check elements, values, etc.).
I did a lot of research, but I can't find the answer or some clue to lead me, given this situation.
How should I do it?
Am I structuring things wrongly to accomplish my goal, or not following good practices?

Express - static file being served cannot be located

I am trying to serve static files (CSS stylesheets) with Express, and it is located when I am on some routes such as the home page / or index page /index. However, when I navigate to a /index/:id page, I get this error in the chrome console:
GET http://localhost:3000/index/stylesheets/styles.css net::ERR_ABORTED
I'm sure that the reason why I am getting this error is because the css file is not actually served in the location stated in the error. I verified that the actual location that it is being served is http://localhost:3000/stylesheets/styles.css.
I have this following line of code in my server file: to serve the css file app.use(express.static(__dirname + "/public"));
and this is the code for the /index/:id route:
app.get('/index/:id', function(req, res) {
Post.findById({_id: req.params.id}, function(err, foundPost){
if (err) {
console.log(err);
res.redirect('/');
}
else {
res.render('./index/show', {post: foundPost});
}
});
});
and I made sure to add the CSS to every html page being served with this exact line:
<link rel="stylesheet" href="stylesheets/styles.css" />
Why is the CSS included for routes such as / or /index, but looks in the wrong place for it when I navigate to a /index/:id page? The location that the page is looking for the css file in changes from http://localhost:3000/stylesheets/styles.css to http://localhost:3000/index/stylesheets/styles.css depending on the route I am on.
What am I missing? Any help is much appreciated!
This works for me-
app.use(express.static('public'));

Saving and loading data in a node.js server and passing it to an html5 file

So I'm very new to node.js and javascript, and i made a server that works great by loading up an html file on request. This html file does not contain any of it's own data, it simply sources from the internet and displays some images and text i wrote. I've decided to make the site play an audio file when it is opened. I know this is done easily with the <audio> tag in html5 but the src="" lets me take a file from the computer and place it there, of course when i open the site from another computer the file obviously isn't found and thus isn't played. I figure the audio file must be kept as a variable on the server and passed into the html file's <audio src= > tag. How do i do this? It is an .mp3(but i can get it to any other audio format) file about 30 seconds long. I just want it to play when the site is loaded from another computer(over the internet). Also how would i go about doing the same with pictures or any other data that i don't want to source from the internet but rather keep as data in my server?
var http = require('http');
var fs = require('fs');
var simpleServer = http.createServer(function(request, response){
response.writeHead(200, {"Content-Type":"text/html"});
fs.readFile('./Picture.html', null, function(error, data){
if(error){
response.writeHead(404);
} else{
response.write(data);
}
response.end();
})
});
simpleServer.listen(80, '0.0.0.0', function() {
console.log('Listening to port: ' + 80);
});
console.log("Server running...");
Short Answer
Bypassing using HTML altogether, you can also simply serve the audio file instead of Picture.html:
fs.readFile("./audiofile.mp3", function(error, data) {
if (error) {
response.writeHead(404);
} else {
response.writeHead(200, { "Content-Type": "audio/mpeg"});
response.end(data, 'utf-8');
}
});
Note:
You will have to replace the filename audiofile.mp3 and the content type audio/mpeg to their appropriate values for the file you want to send.
Check Mozilla's Complete List of MIME Types for a full list of file extensions and their associated content types.
Better Answer:
The http module is fairly low-level and is unnecessarily complicated if you're learning.
You can install express.js to your project using the command npm install express --save.
With express your code simplifies to:
const express = require('express');
const app = express();
const port = 80;
app.get('/', (request, response) => {
response.sendFile(__dirname + '/Picture.html');
});
// Anything put in the public folder is available to the world!
app.use(express.static(__dirname + '/public'));
app.listen(port, () => {
console.log(`Listening on port: ${port}`)
});
Then you just have to place all your files into a folder called "public" under your project directory and you can call them from HTML!

Node.js - Loading Files in Runtime

I'm fairly new to Node.js and am having trouble understanding the way to go about loading libraries or files, in runtime.
Apparently, it is a bad idea to load files in runtime using Node.js's native "require" function because it is blocking i/o, and therefore should not be used from within request handlers. So, I'm assuming something like this is to be avoided:
var http = require('http').createServer(function(req, res) {
var file = require('./pages/'+req.url);
res.end();
}).listen(8080);
So then is there a way to require files in runtime, in a non-blocking/asynchronous way?
I don't think it would always be possible to load files in "boot time" rather than runtime because like in the example above, the only way to know what file to load/require is by getting the name through the req.url property.
So that seems like the only option. Unless, all the files in the folder are preloaded and then called upon by name, in the callback (By using fs.readdirSync or something to iterate through all the files in the folder and compare the gotten files' names to the req.url property), but that seems wasteful. "Preloading" all the files in the folder (maybe around 50 files) and then only using 1 of them, doesn't seem like a good idea. Am I wrong?
Either way, I would just like to know if there is a way to require files in runtime in a better, non-blocking/asynchronous way.
Thank you!
The function require() is generally used for caching modules or configuration files before most of your application runs. You can think of using require() somewhat like this:
var file = fs.readFileSync('/path');
// depending on the file type
eval(file);
JSON.parse(file);
The reason it is done this way is so that dependencies are loaded in order. If you want to read a file after initializing the application, you should use a asynchronous read, and respond in the callback like this:
var http = require('http');
http.createServer(function(req, res) {
fs.readFile('./pages/' + req.url, function(err, data) {
res.end(data);
});
}).listen(8080);
If you needed to check if a file existed, then you could use fs.stat() to check the existence of a file, rather than querying the directory.
var http = require('http');
http.createServer(function(req, res) {
var file = './pages/' + req.url;
fs.stat(file, (err, stats) {
if (err || !stats.isFile()) {
res.writeHead(404);
res.send();
return;
}
fs.readFile(file, function(err, data) {
res.writeHead(200);
res.end(data);
});
});
}).listen(8080);

how can i render html file in node.js

i have tried to render html file but i got this error . i have login.html within public folder.how to render html file.thanks in advance.
my server side coding
var express = require('express');
var app = express();
app.configure(function(){
app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));
});
app.get('/', function(req, res) {
res.render('login.html');
});
app.listen(8000)
Error: Failed to lookup view "login.html"
at Function.render (/home/aware/local/src/node_modules/express/lib/application.js:493:17)
at ServerResponse.render (/home/aware/local/src/node_modules/express/lib/response.js:753:7)
at /home/aware/local/src/health/demo2.js:17:9
at callbacks (/home/aware/local/src/node_modules/express/lib/router/index.js:161:37)
at param (/home/aware/local/src/node_modules/express/lib/router/index.js:135:11)
at pass (/home/aware/local/src/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/home/aware/local/src/node_modules/express/lib/router/index.js:170:5)
at Object.router [as handle] (/home/aware/local/src/node_modules/express/lib/router/index.js:33:10)
at next (/home/aware/local/src/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at resume (/home/aware/local/src/node_modules/express/node_modules/connect/lib/middleware/static.js:60:7)
The closest you can get to using html for node views is EJS (Embedded JavaScript)
This way you write your normal HTML, pass your data through node and display them using tags like: <%= var %>
http://embeddedjs.com/
https://github.com/visionmedia/ejs
You can render HTML page with Nodejs using Embedded JavaScript(ejs).
here you can go through -the Documentation of ejs
for using ejs, first of you create directory with the name views, In that directory create a file with .ejs extension.
The files you keep inside your public folder will not be rendered because they are set as static, so they will be served as is. All other files outside of this will be rendered. Remember to set the rendering engine.
I just came in contact with connect today & wanted to solve a simillar issue, serving a simple HTML file. In my case, I wanted to display a 404 when any previous middlewares hadn't finished the request.
I create a function, show404 and then you can do something like app.use(show404). Here's my CoffeScript for that mostly inspired in connect errorHandler source code.
show404 = (req, res, next) ->
res.statusCode = 404
res.setHeader 'Content-Type', 'text/html; charset=utf-8'
html_path = require("path").resolve('.tmp/404.html')
require('fs').readFile html_path, (err, data)->
throw err if err
console.log "DATA:", data
res.end data

Categories

Resources