Why res.send( string ) download a file - node.js

I have an app where I want to render static html with express.
I know about res.sendFile() but that is not what I want to use. I want to load my files using fs and send them using res.send()
I do something like this :
fileFoo = fs.readFileSync('./html/foo.html', 'utf-8');
fileBar = fs.readFileSync('./html/bar.html', 'utf-8');
app = express()
app.get('/foo', (req, res) => res.send(fileFoo));
app.get('/foo/bar', (req, res) => res.send(fileBar));
With 2 very simple html files
foo.html
<html>
<head>
<title>FOO</title>
</head>
<body>
<h1>FOO</h1>
bar
</body>
</html>
bar.html
<html>
<head>
<title>BAR</title>
</head>
<body>
<h1>BAR</h1>
</body>
</html>
When I go to /foo I got a HTML rendered.
If I click on bar I do not get a new HTML page rendered but I got a file "bar" with no extension downloaded. The file of course content the HTML page.
What is happening ?
UPDATE :
I am actually using a router, not direct app.
And I think this 'download' occure only when I try to reach
router.get('/', (res, req) => res.send(fileBar));

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.

Are there Application scope variables in Node js

I wanted to know are there any application scope variables that can be accessed anywhere in the whole application.
Since I want to add data to my HTML tags using javascript, I need to transfer/get data from the server.js to the index.html
To transfer data from server.js to index.html you don't need to create global variables. You need to use a templating engine: pug, ejs or any other engine.
Just pass the data along with html file in the res.render() function and use templating syntax to display the data at the page.
Router code:
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!'});
});
Pug code:
html
head
title= title //Hey
body
h1= message //Hello there!
ejs code:
<html>
<head> <%= title %> </head>
<body>
<h1> <%= message %> </h1>
</body>
</html>

Express only serving css file in main page

I am learning node and using expressjs the problem is that the css file is only working on the main page and not any other page following is the code for the app:
var express = require("express");
var app = express();
// assets
app.use(express.static("public"));
// simple file testing
app.get("/anything/:stuff", function(req, res){
var stuff = req.params.stuff;
res.render("love.ejs", {stuff: stuff});
});
// posts page
var books = [
{title:"Harry Potter",author:"JK Rowling",editions:7},
{title:"Peere Kamil",author:"Humaira Saeed",editions:4},
{title:"Mushaf",author:"Abdullah khan",editions:2}
];
app.get("/books", function(req, res){
res.render("books.ejs",{books:books});
});
app.listen(3000, process.env.IP, function(){
console.log("Serving Now!");
});
The following is the code for the page where it is not working.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="app.css" />
<title>demo app</title>
</head>
<body>
<h1>You fell in love with : <%= stuff %> </h1>
<%
if(stuff.toUpperCase() === "WAQAS"){ %>
<P>GOOD CHOICE HE IS THE BEST</p>
<% } %>
<p>P.S This is the love.ejs file</p>
</body>
</html>
The file is under public directory.
Use an absolute URL for the CSS file, so the browser doesn't look for it relative to the current URL:
<link rel="stylesheet" href="/app.css" />
Explanation: say that you open the URL /anything/helloworld in your browser. When your HTML contains just app.css, without the leading slash in front of it, the browser will try and load /anything/app.css (because without that slash it's relative to the current URL), which doesn't point to your CSS file.
When you add the leading slash, express.static will be able to find the CSS file in public/.

React Components on the Server

I've been playing around with React for a while now but still can't wrap my head around on how to integrate it with an existing node/express/handlebars app.
For example, if I had a feed component which required json data to be fetched from AWS - how do I handle this.
var VideoFeed = require('./component/VideoFeed');
app.use('/', function(res, req) {
DataService.getVideoFeed().then(function(data) {
res.render('home', {videoComponent: React.renderToString(<VideoFeed feed={data} />);
});
});
Home
<!DOCTYPE html>
<body>
Some sample text. Here's the Video Feed
{{videoComponent}}
</body>
</html>

Can someone explain why this code is working?

So i am using marked (a markdown module) with express, i am not setting the title var or rendering anything and yet the title var is being mutated -i guess- here is the code to my index.js route :
/*
* GET home page.
*/
exports.index = function(req, res, marked){
marked('Why is this even __working__?.');
};
and here is the code to my index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>
and here is what i am getting in the browser, although i restarted the app so many times!!:
You have misunderstood the connect/express middleware function signature. You have:
exports.index = function(req, res, marked){
But that's not right. It's req, res, next and there's no marked involved. So you aren't rendering markdown, you're passing a string to next() which connect/express treat as an error. Your code does this once you remove the misnamed function parameter confusion:
exports.index = function(req, res, next){
next('Why is this even __working__?.');
}
So connect sees next was passed an error string and express render's the default error page with that as the error message.

Resources