In my main app.js file I have this piece of code:
app.use(function (req, res, next){
res.locals.currentUser = req.user;
next();
});
... which as you can see serves to get the user info from the passport. And it does it's job... that is until it is used more than once. Whenever I login as a user, and I hit any other routes, that should trigger the res.locals.currentUser to update... but it doesn't. It stays on the old value.. And I can't for the life of me figure out why. I've read the documentation and triple checked everything. Nothing seems to be out of order.
HERE is all of the code.
Most important files:
Main file
Header
Index Page
IMPORTANT NOTE: Every other instance of trying to get the user from passport by directly asking for it from passport works like a charm. Example is the line 58 in the main file:
res.render("campgrounds/index", {campgrounds: campgrounds, user1: req.user});
,that corresponds to lines 7-11 from the index page:
<% if(!user1) { %>
<h1> Welcome to YelpCamp! </h1>
<% } else { %>
<h1> <%= user1.username %>, Welcome to YelpCamp! </h1>
<% } %>
It returns the user data correctly every time. Any ideas why this is reacting this way? Thanks.
Related
When accessing my web app, when im at the home page (not logged in) my function that basically does
function isNotAuthenticated(req, res, next) {
if (req.isAuthenticated) {
res.redirect('/');
else {
return next();
}
}
However, when first accessing the home page (not logged in) this function returns true and claims i am logged in.
When checking the req.user, however, it says its undefined.
Anything come to mind as to why my functionality isnt working? its all inside of 1 file called app.js (know this works because there are several youtube tutorials out there that i've followed).
Is it anything to do with the ordering of my app.use functions?
Any help would be lovely, thanks.
EDIT;
Solved! Missed the brackets at the end of the function 👍
I have 3 main code classes:
1) node.js (running express)
2) the index.html (which loads the moment we enter the site)
3) sck.js which does something (I will explain it after the first and second files)
what I basically do is, I want the user to click on a button. and then the server will output on the page (HTML) or, alert (does not matter to me)
a specific line/word...
I am going literally crazy, I've searched everywhere...
I don't want the user to see the secret word until he clicks the button. not even in the source code (F12) !!!
sck.js is just a jquery that listens to a button click.
app.js:
const express = require('express');
const path = require('path');
const app = express();
//Set a static folder
app.use(express.static(path.join(__dirname, 'public')));
app.listen(3000, ()=>{
console.log(`starting server port 3000`);
} );
in index.html there is just a button, waiting for the user to click it.
TL;DR : how do I make a variable COMPLETELY invisible for the user, until he clicks a button?
I thought about saving the secret in app.js (because the user cant see whats written there...) and then passing it somehow to the html... but I cant!!!
doesn't it suppose to be easy? it sounds like that .... :(
Thanks!!
A super simple way. Add a route to your express app:
app.get('/getflag', function (req, res) {
res.send('theflag');
});
Add a link to your HTML
Get Flag
Click the link, you will be taken to a page with 'theflag' displayed.
I'm currently stuck with a problem in a homework project. I'm trying to make a project where the price of bitcoin will update every second. Now the API request is working fine and I can see the data render from an EJS template but I can't make the price update every second. Can anyone check my code and see if anything is wrong in my code? For reference please check www.preev.com. It shows how I want the price to be updated. And also check below my code.
I have tried to call the API request in app.js file and rendered it in an EJS template called results.ejs.
app.js
var express = require("express");
var app = express();
var request = require("request");
app.set("view engine", "ejs");
app.get("/", function(req, res) {
request("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true&include_last_updated_at=true", function(error, response, body) {
if(!error && response.statusCode == 200) {
var data = JSON.parse(body);
res.render("result", {data: data});
}
});
});
app.listen(3000, function(){
console.log("server has started");
});
results.ejs
<h1>
Bitcoin Latest
</h1>
Price: $ <span id="showPrice"></span>
<br>
MarketCap: $<%= data["bitcoin"]["usd_market_cap"] %>
<br>
24h Volume: $<%= data["bitcoin"]["usd_24h_vol"] %>
<br>
24h Change: <%= data["bitcoin"]["usd_24h_change"] %>%
<script>
function updatePrice(){
document.getElementById("showPrice").innerHTML= <%= data["bitcoin"]["usd"] %>;
};
setInterval(updatePrice, 500);
</script>
Initial answer
Your setInterval works fine, it's just that inside your function the data never changes.
To fix it you have to reference a variable (of which the content changes), rather than hardcoding the value in your function.
Extra explanation
For example you are using EJS, which is a templating language. A templating language parses output based on your variables (once per page load).
Your template line
document.getElementById("showPrice").innerHTML= <%= data["bitcoin"]["usd"] %>;
parses into
document.getElementById("showPrice").innerHTML= 9624.46;
And your interval then updates the innerHTML of #showPrice with that value, every 500 ms.
What you probably mean to do is make the request from the client (the browser), then store its response into a variable, say latestResult, and then code your function to reference that variable, like so:
document.getElementById("showPrice").innerHTML= latestResult;
Example implementation
This means that your express application (app.js) will render result without data:
app.get('/', function(req, res) {
res.render('result');
});
And the request part will be in your template:
function updateLatestPrice() {
fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true&include_last_updated_at=true').then((result) => {
const latestResult = result.bitcoin.usd
document.getElementById("showPrice").innerHTML = latestResult || 'failed'
})
}
setInterval(updateLatestPrice, 3000)
Note that I changed request into fetch here because I couldn't be sure whether your client code has babel, so I went with the browser's native Fetch API.
I have been asked to perform following task
Take a code input from frontend, i.e user would give his code on frontend (design for a web/landing page)
On backend we have many fields inside an api route
route.get("/", (req, res) => {
const fullName: "Varun Bindal"
const contactNo = 9293939933
const message = "Message I want to display"
//Many more
}
Tell user a way where when we serve his code such that, he could dynamically access/assign the fields we have in the backend into his code
I did some googling and found the express officially recommends ejs for server side compilation of webpage
Can someone please help me figure out how we can achieve this?
Yes you can!
Firstly you must include ejs in your project, configure it in your server.js file for example, then you can call res.render() in your callback parameter on route.get().
In your html or javascript you can create a placeholder which gets populated.
Example (server):
route.engine('html', ejs.renderFile);
route.engine('js', ejs.renderFile);
route.get('/', (req, res) => res.render(path.resolve(__dirname, '
../ui/index.html'), {
'myVal': 42,
}));
Example (client html, js, etc...):
<%= myVal %>
I want to be able to flash a message to the client with Express and EJS. I've looked all over and I still can't find an example or tutorial. Could someone tell me the easiest way to flash a message?
Thanks!
I know this is an old question, but I recently ran across it when trying to understand flash messages and templates myself, so I hope this helps others in my situation. Considering the case of Express 4, the express-flash module, and an ejs template, here are 2 routes and a template that should get you started.
First generate the flash message you want to display. Here the app.all() method maps to /express-flash. Request baseurl/express-flash to create a message using the req.flash(type, message) setter method before being redirected to baseurl/.
app.all('/express-flash', req, res ) {
req.flash('success', 'This is a flash message using the express-flash module.');
res.redirect(301, '/');
}
Next map the message to the template in the res.render() method of the target route, baseurl/. Here the req.flash(type) getter method returns the message or messages matching the type, success, which are mapped to the template variable, expressFlash.
app.get('/', req, res ) {
res.render('index', {expressFlash: req.flash('success') });
}
Finally, display the value of expressFlash, if it exists, in index.ejs.
<p> Express-Flash Demo </p>
<% if ( expressFlash.length > 0 ) { %>
<p>Message: <%= expressFlash %> </p>
<% } %>
Then start the server and visit baseurl/express-flash. It should trigger a redirect to baseurl/ with the flash message. Now refresh baseurl/ and see the message disappear.
<% if ( message ) { %>
<div class="flash"><%= message %></div>
<% } %>
Is this what you want? You can use some client-side JS to have it fading out. jQuery example:
var message = $( '.message' );
if ( message.length ) {
setTimeout( function() {
message.fadeOut( 'slow' );
}, 5000 );
}
req.flash() can be used in two ways.
If you use two arguments
req.flash(type, message);
where type is a type of message and message is actual message (both strings), then it adds message to the queue of type type. Using it with one argument
req.flash(type);
returns array of all messages of type type and empties the queue. Additionally this method is attached to the session, so it works per session. In other words, each user has its own set of flash queues. So in your view you can do something like this:
var messages = req.flash('info');
and then send the messages variable to the template and use it there (note that messages is an array and you can iterate it). Remember that using req.flash('info', 'test'); will append a test message of type info only for a current user (associated with the req object).
Keep in mind that this mechanism is quite weak. For example if a user double clicks on link (two requests send to the server), then he will not see messages, because the first call will empty the queue (of course unless the request generates messages).
I was struggling with this as well; Getting my flash message to appear in my .ejs.
BUT, I finally got it to WORK and this is what I understand.
Once the getter req.flash('_msgName_'); is called it is cleared!
Also when you app.use(session()); cookie must equal cookie: {maxAge: 720}, essentially a big number.
I was using a console.log() to test the getter, and it was displaying in my console, but not in my .ejs. I took the console.log() out and it worked.
Here is some of my code.
Server.js ~
app.get('/', function(req, res) {
// This is where we will retrieve the users from the database and include them in the view page we will be rendering.
User.find({},function(err, allUsers){
if(err){
console.log("Oh no we got an error\n ERROR :: "+err);
} else {
// console.log(allUsers);
res.render('index',{users : allUsers, msg : req.flash('vError')});
}
});
});
// Add User Request
app.post('/users', function(req, res) {
console.log("REQUESTED DATA:\t", req.body);
var user = new User(
{
name: req.body.name,
age: req.body.age
}
);
// Saves user to DB.
user.save(function(err) {
if(err) {
console.log('OOPS, Something went Wrong... \n ERROR :: '+err+'\n');
for(var key in err.errors){
// console.log(err.errors[key].message);
req.flash('vError', err.errors[key].message);
}
// **HERE I WAS ACCIDENTALLY CLEARING IT!!!** \\
// console.log(req.flash('vError'));
// res.render('index',{users : [], msg : req.flash('vError')});
res.redirect('/');
} else {
console.log('\tSuccessfully added a new User to the DB!');
res.redirect('/');
}
})
});
index.ejs ~
<% if(msg.length > 0) { %>
<% for (var error in msg) { %>
<h3><%= msg[error] %></h3>
<% } %>
<% } %>
If you use visionmedia's express-messages helper module, it becomes very simple. Github link
As it says in the module's docs:
Install the module with npm
npm install express-messages
You then assign a dynamic helper for messages in the app.config:
app.dynamicHelpers({ messages: require('express-messages') });
In your EJS file, insert the following where you want your messages
<%- messages() %>
EJS renders this into:
<div id="messages">
<ul class="info">
<li>Email queued</li>
<li>Email sent</li>
</ul>
<ul class="error">
<li>Email delivery failed</li>
</ul>
</div>
(of course, you can alter what it renders to in the module's code)
Then, to actually flash a message, include a call to:
req.flash('info', 'Your message goes here');