Access localStorage from ejs template - node.js

I am trying to save some data sent by the server to an EJS template in localStorage on the client side. However, when I try to access localStorage in the template, I get localStorage is undefined.
Here is a part of my page.ejs:
<% localStorage.setItem('info', JSON.stringify({'user': user})) %>
where user is a value received from the server.
Is this possible?

There are a few options depending on what you want to do. I came across this post looking to do something a little different but here is one way:
After the template renders and passes the data user, add a script tag to modify localStorage.
<!-- example.ejs -->
<!-- check for user on page load -->
<% if (typeof user != "undefined") { %>
<!-- make user available to script tag -->
<% var user = user %>
<!-- use script tag to access ejs data and local storage -->
<script>
let user = <%- JSON.stringify(user) %>;
localStorage.setItem('info', JSON.stringify({'user': user}));
</script>
<% } %>

check this once its worked for me,
<script>
let data =JSON.parse('<%- JSON.stringify(data) %>')
localStorage.setItem("data", JSON.stringify(data))
</script>
and for accessing,
<script>
let data = JSON.parse(localStorage.getItem("data"))
</script>

Related

How to load a javascript file only in some ejs templates?

I am building an app with the help of node, express and ejs. The structure of my app is in this way that I used a footer.ejs file in all pages (templates) and in that file I have a code like this:
footer.ejs
<!-- bootstrap js CDN -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<!-- some other codes -->
</div>
</body>
</html>
But in some of my pages I need some js codes. Because I don't want to load them in un-related pages, I decided to add the <script> tags of them individually on that page only like the code below:
information.ejs:
<!-- the html tags of this page (called information.ejs) are here -->
<!-- ... -->
<!-- end of html tags -->
<script src="/javascripts/upload.js"></script> <!-- this is the script codes that only need in this page -->
<%- include('include/footer') %>
That works fine. But now I need some functionality of bootstrap.js in my upload.js script. The problem here is that upload.js is loaded before the bootstrap.js and I could not use the functionality of bootstrap in my script.
To solve that problem I decided to define a variable called infoId and send that to information.ejs like below in my express router file:
router.get('/dashboard2/:infoId', (req, res) => {
res.render("information", {
infoId: req.params.infoId,
});
})
And then deleted the script tag from the end of information.ejs file and added it in footer.ejs like below:
new footer.ejs:
<!-- bootstrap js CDN -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<!-- added new -->
<% if(infoId !== undefined) { %>
<% if(infoId == "information") { %>
<script src="/javascripts/upload.js"></script>
<% } %>
<% } %>
<!-- some other codes -->
</div>
</body>
</html>
In this case I get the error of variable infoId is undefined when I navigate to other routes (pages). Could I fix this problem without sending the infoId variable to all other routes?

How do i make the ejs variable work that i send from nodejs?

I am tring to get a variable that i send from nodejs to ejs to work. But for some reason it wont, i cant figure out why.
This is the index.js:
var newOne = "Yes"
router.get('/main', ensureAuthenticated, (req, res) =>
res.render('main', {
user: req.user,
newOneInView : newOne
})
)
And this is in the main.ejs file:
<%if (newOneInView == "Yes") { %>
document.getElementById("avatar").src = "/static/images/Apocaliptic1.png";
<% } %>
So what i am trying to achieve is that variable will be seen from the nodejs at the main.ejs page but some reason it wont change the image SRC. What am i doing wrong here?
In your template you need to make sure that you place the code for changing the src attribute in a script that is placed after the element (alternatively you can use a listener for the content to be loaded), e.g:
<body>
<img id="avatar" src="/some-other-path"/>
<script>
<% if (newOneInView === "Yes") { %>
document.getElementById("avatar").src = "/static/images/Apocaliptic1.png";
<% } %>
</script>
</body>

Node.JS :How to forward to the login page with parameter?

I am building the login function with node.js, express,express-session, ejs.
This is the log-in page (i.e. index.ejs)
<html>
<head>
<meta charset="UTF-8">
<title>Video Chat Room</title>
<link rel="stylesheet" type="text/css" href="/css/style.css">
<style>
#message
{
color:red;
font-weight: bold;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$( document ).ready(function() {
var messageBox=document.getElementById("message");
<%
if (typeof errorField!="undefined") {
switch (errorField) {
case "email":%>
messageBox.innerHTML="Your email address has been used by another user, please use another one.";
document.getElementById("email").focus();
<% break;
case "logoutSuccess":%>
messageBox.innerHTML="<%=alias%> has successfully logged out.";
<% break;
}
}
%>
});
</script>
</head>
<body>
<form method="post" action="/login">
Nick name/Alias:<input type=text required name="alias" value="<%=((typeof user=='undefined')?'':user.alias)%>"><br>
Email Address:<input type=email id="email" required name="email" value="<%=((typeof user=='undefined')?'':user.email)%>"><br>
<input type="submit" value="Login">
</form>
<div id="message">
</div>
</body>
</html>
Here is the server-side code(i.e. server.js)
........
app.get('/',function (req,res) {
res.render('../ejs/index.ejs');
});
app.post('/login', function(req, res) {
var alias = req.body.alias;
var email = req.body.email;
var user=require("./classes/user.js");
user.alias=alias;
user.email=email;
if (user.login) {
req.session.user = user;
res.redirect('/home/');
} else {
res.locals.errorField="email";
res.locals.user=user;
res.render('../ejs/index.ejs');
}
It works fine, however, when the login process failed, although the web output the login page(i.e. index.ejs), the browser address bar still stay in "/login"; is it possible to change the browser address bar to "/" and the index.ejs can read the errorField and user value also?
If you want a user login error to go back to /, then you need to do res.redirect("/"). If you want to add some parameters to that page that can be used either in server-side rendering or client-side rendering, then the simplest way to do that is to add query parameters:
res.redirect("/?error=email")
Then, either your server-side rendering or some client-side Javascript can pick up that query parameter and display something like a message in the page that explains what happened.
There are lots of ways to do something like this. Here's a partial list:
Send data in a query parameter that server-side rendering picks up and adds some explanatory text to the page.
Send data in a query parameter that client-side Javascript picks up and adds some explanatory text to the page.
Set a cookie that contains an error message that your server-side rendering will pick upon the redirect and then clear the cookie.
Set some error data in the user session object on the server that your server-side rendering will pick up when rendering the redirected page and the clean that info from the session.
Use an Express middleware module built for these temporary messages called flash.
Render an error page from the server (without an immediate redirect) and then have a client-driven redirect back to "/" that occurs after a few seconds time. The client-driven redirect can either be from a <meta> tag or can be client-side Javascript on a timer.

SweetAlert2 is not working in node.js

I'm making website for db study.
I wanted to alert to user if user didn't input id and password in register page.
So I installed sweetalert2 by npm. But sweetalert2 doesn't work in route.js which connect user's ask and server.
var swal = require('sweetalert2');
router.post('/register', function(req, res){
if(!req.body.id && !req.body.password){
swal('WARNING','You must input both id and password!','error')
}
else{
swal('COMPLETE','You registered your information!','success');
res.redirect('/');
}
})
How can I fix it?
I used .ejs file to use sweetalert2.
<!DOCTYPE html>
<html>
<head>
<% include ../pages/head %>
</head>
<body>
<% if(fail) { %>
<% include ../partials/alert_login %>
<% } %>
<% include ../pages/login %>
</body>
</html>
in login_connect.ejs includes when user fail login alert_login.ejs file and alert_login.ejs includes script tag of using swal of sweetalert2 module.
But It isn't work. What is the problem?
alert_login.ejs is below.
<script type="text/javascript">
alert("You are not our member!");
</script>

Update EJS Layout with Session

My ejs layout provides the current user's username on the main menu through sessions
<a href="">
<% if (typeof currentUser === 'undefined'){%>
<% } else { %>
<a style="text-decoration:none;" href="/users/logout">Logout</a>
<% } %>
</a>
Now when I destroy the session and redirect to the main page, the currentUser's infomation is still showing, although logging currentuser returns undefined. Is there a way to force the layout to update itself to show current information?

Resources