I was learning Express/Node/Jade and now in the Jade file I want to include a javascript file from the public folder just for the page.
For example, in jade file I type this:
script(src='/javascripts/test.js')
and inside test.js I have a function
function check_test(){
return "It's working!"
}
then I try to call the function in Jade by
- var test_response = check_test()
than I got the error saying that "undefined is not a function" and test.js isn't load at all.
Apparently Jade doesn't load the file, they only transform into HTML code.
I look someone else's question and this is the closest one I can found but it doesn't provide a clear answer of what to do.
In Jade, how can you call a function in an external Javascript
So my question is: In this case what should I do to make it work?
I don't want to load the file in layout.js since I only want test.js only be use by this page.
Well... In the first instance, it is different what happens in the browser of what happens on the server. So Jade is a rendering of HTML, therefore if you are in the browser. It's what ExpressJS shipping, ie rendering Jade. If you want to call, your HTML Javascript (Rendering of Jade), should show you where the Javascript. For exmaple
in Server.js
// Get the Javascript in the browser
app.use("/javascripts", express.static("./outJavascripts"));
// Get the URL
app.all("/", function(req, res){
// Render the Jade and Send for the client (Browser)
req.render("myTemplate.jade");
});
In myTemplate.jade
script(src='/javascripts/test.js')
In "./outJavascripts/test.js"
function check_test(){
console.log("It's working! :D");
return "It's working!";
}
If you do this, you will realize that it is run, the file "./outJavascripts/test.js" in the browser. And the function "check_test" never run in the server.
Or put all folders in a common folder, for example public
public
-javascripts
-stylesheets
-images
and then expose that public folder
app.use(express.static(path.join(__dirname, 'public')));
which means you can
script(src='/javascripts/script.js')
link(rel='stylesheet', href='/stylesheets/style.css')
Save your JS file and link it in your Jade file as:
script(src="filepath/yourJSfile.js")
Then call the function, I'm using a button here for example:
button(class="btn", onclick='functionName()')
Related
I am writing a website using NodeJS and Express. After specifying a link with 2 route parameters:
app.get('/game/:port/:player/', function(req, res) {
res.sendFile(path.join(__dirname, '/game/game.html'));
})
-the result is a blank white page.
Looking at DevTools, I saw the error Uncaught SyntaxError: Unexpected token '<' game.js:1. It looks like the browser is interpreting the html file as a JavaScript file! I think this is because the browser tries to fetch the js and css files from /game/(portnumber)/(playernumber) instead of from /game. And the css shows up as the actual HTML file:
However, another route that I have with only 1 route parameter works just fine! I am still relatively new to Express so I don't really understand how fetching directories works.
Is there any way to fix this directory error without manually specifying every single path in which there are HTML files?
This doesn't really have anything to do with Express. It is basic URL resolution.
The browser will request /game/3561/2 and get an HTML document back
That document will tell it to load ./game.js which it will resolve to
/game/3561/game.js (since a URL starting with a . means "resolve the path from current directory").
That isn't the URL of your JS file, so you get an HTML document instead — where :player is game.js.
You need to write the actual URL to your JS file in the src attribute.
You can use the express.static middleware to specify a public directory your clients have access to:
https://expressjs.com/en/starter/static-files.html
app.use('/static', express.static('public'))
http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html
I have a folder
api-docs inside that I have index.html some css and js file
I need to render api-doc for authenticated user.
I am not using it in views as In project I am using jade in view and api-doc is in html
I have tried
router.get('/v1/secure-api-documentation',(req,res)=>{
console.log('A')
res.sendFile(__dirname + '/../api-doc/index.html');
});
and
router.get('/v1/secure-api-documentation',ensureAuthenticate,(req,res)=>{
express.static(path.join(__dirname,'../api-doc'))
});
express.static(path, [options]) returns a function. So basically what your code is doing is :
router.get('/v1/secure-api-documentation',ensureAuthenticate,(req,res)=>{
express_static_function // this function further accepts arguments req, res, next
//there is no function call happening here, so this is basically useless
});
However, this is not what express.static is used for
What express.static does is, takes the request path and looks for a file with the same name in the folder you specified.
Basically, if a GET request comes to '/v1/secure-api-documentation', it will take the request path after '/v1/secure-api-documentation' and look for that inside api_docs folder.
Passing express.static to router.get() will call it for the very SPECIFIC path. This is important.
GET '/v1/secure-api-documentation/index.html' will fail. Because such a route is not handled.
What you need to do this is call express static for any path like '/v1/secure-api-documentation/*'.
For this you need to take the express app object, and write the following code:
//make sure to use the change the second argument of path.join based on the file where your express app object is in.
app.use('/v1/secure-api-documentation',express.static(path.join(__dirname,'../api-doc')));
This will now work for not only the index.html file but any js/css file inside api_docs that is requested.
I'm currently using a expressJs template that uses pug in order to make a simple website. On the site is a button. I want on the click of the button to call a function in the index.js file.
Originally I had the code like this. In the index.pug file:
extends layout
block content
h1= title
p Welcome to #{title}
button#BubbleButton.button.hypeButton.button-3d.button-caution.button-circle.button-jumbo(onclick = 'buttonClick()') Click
In my index.js file, it would look like so:
var express = require('express');
var router = express.Router();
var PubNub = require('pubnub');
module.exports = router;
function buttonClick(){
alert('test');
}
However, I would get a response along these lines:
buttonClick function not found.
I'm frankly more familiar with angular than pug. What does it take to link up the view side to the router file? I understand in Pug, you can add an endpoint REST API style, but this isn't necessarily going to be an API. I may just want to show something simple and not expose it. However, I may be misunderstanding something fundamental.
Thanks!
The JavaScript code contained in the script. tags in your pug file will only run in the browser, and the code in index.js will only run on the server. Therefore they can never speak directly.
You need an ajax call on the client (i.e. in your pug file). Here's an example using jquery but you can use one of the many ajax client packages out there to do the same thing:
script.
function onButtonClick(){
$.ajax({
"url": "/service",
"method": "POST"
});
}
Then you need a route handler in index.js:
router.post('/service', function(req, res){
console.log('test');
});
Note that this will output to the console on the server, not the client. I believe that's what you want to do.
To add jquery to your page you can use a cdn (Content Delivery Network) to quickly bring it into your code. Here is the pug syntax for that:
script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous")
Alternatively you could you axios as a lightweight alternative to jquery, all it does is ajax:
script(src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js" integrity="sha256-mpnrJ5DpEZZkwkE1ZgkEQQJW/46CSEh/STrZKOB/qoM=" crossorigin="anonymous")
It all works in my local server, but when others try to deploy what I have done to the server, it fails.
the file system is the server something like:
SERVER_FOLDER
--homepage
----static
----templates
------404.html
----app.py
----config.py
for example: The server is: MY_SERVER
and then in my app.py, I use
#app.route('/homepage/')
#app.route('/homepage/index')
def index():
# TODO
to define the homepage, and #app.errorhandler(404) to redirect all the not found page to 404.html
So I can get access to my homepage with http://MY_SERVER/homepage/, a little different than my local server. That's one thing that I am confused.
What I think is that the app.py runs under the MY_SERVER rather than MY_SERVER/homepage right?
But, in this way, when I run a template in my template file, and the html template file will use the js file under the static folder. the response always shows the js file is not found.
when I use <script src="{{ url_for('static', filename='file.js') }}"></script>, it shows not found in MY_SERVER/static and return to 404
when I try <script src="../homepage/static/file.js"></script>, same result.
How to handle this?
Build toward your solution:
Get flask serving image files from static
Put an image in the static directory and call it from your browser: http://yoursite/static/some_image_there.jpg
Plug away until that works.
Get flask serving the js file directly to your browser
Now put your js file into static and do as you did for the image.
Plug away until you can call it from the browser:
http://yoursite/static/yourfile.js
get your html to call the js file from static
Now you know that there is no problem actually serving the file, and you know the exact url to it. So it's not a big step to getting the HTML to reference it and your browser to load it.
I've been doing some guide on Mean stack and I came to a point where I'm currently stuck.
Following this guide, I have created a simple authentication where I'm able to log in using Passport JS. Whatsoever, each time when page refreshes, the authentication gets restarted (client doesn't recognise it anymore).
Since this is suppose to happen in the guide and we are about to fix it, guide said the following.
1. Create a Jade file and insert this:
if !!bootstrappedUser
script.
window.bootstrappedUserObject = !{JSON.stringify(bootstrappedUser)}
I've tried this in my html file but it doesn't work:
<script type='text/javascript'>
if (bootstrappedUser != "undefined" ){
window.bootstrappedUserObject = JSON.stringify(bootstrappedUser);
}
</script>
Getting the error: Uncaught ReferenceError: bootstrappedUser is not defined
even though I have created the variable in my backend js file and assigned req.user to it.
I'm suppose to have this file included in my main layout (index.html). The problem is that I'm not using Jade as template engine but plain HTML and I don't know how to transform this code up there to work as simple HTML in my index.html.
It seams that this statement up here only initialise when user hits the login button. Does anyone have any idea or solution how to write the above code in plain HTML.
I browsed StackOverflow and found almost similar problems but not similar enough.
Thanks in advance,
Aleksandar
bootstrappedUser is a variable passed by server-side code to Jade compiler which injects it into the HTML while compiling. If you plan on writing the HTML yourself you can not inject variables from server-side code, obviously because HTML is just a static markup. You'll probably have to get that variable at the client-side from the server yourself via ajax or something.
Via Angular controller let's say ?
You can first define a route on server that serves the variable you want
app.get('/bootstrappedUser', function(req, res){
if(req.user)
res.json(req.user);
else
res.status(401).end();
});
Then on client-side angular you can perform an http request and get that variable
$http.get('/bootstrappedUser')
.success(function(data, status, headers, config) {
$scope.bootstrappedUser = data;
});