Passing data from one page to another using Node, Express & EJS - node.js

I've got the following routes set up:
router.get('/', function(req, res) {
res.render('index', {});
});
router.post('/application', function(req, res) {
res.render('application', {twitchLink : req.query.twitchLink});
});
I've got the two views set up properly.
This is what I've got in the 'index' view:
<form class="form-horizontal" action="/application", method="post", role="form">
<input type="url" name="twitchLink" required>
<button class="btn btn-success">Submit</button>
</form>
Submitting this form does take me to the application view.
<script>var twitchLink = <%- JSON.stringify(twitchLink) %></script>
<script>console.log(twitchLink)</script>
This should log out the link that I submitted, right?
However, I get these two lines:
Uncaught SyntaxError: Unexpected end of input
Uncaught ReferenceError: twitchLink is not defined

I think you need to put quotes around <%- JSON.stringify(twitchLink) %>, like this:
var twitchLink = '<%- JSON.stringify(twitchLink) %>'
In your example, it will come out as:
var twitchLink = foo.bar.com
What you want is:
var twitchLink = 'foo.bar.com'

Related

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>

Send Data from Span in EJS to Server Nodejs

Using Nodejs, Express, EJS
I see a lot of 'Send Data from Server to Client' but not from Client to Server AND sending the data from a tag not from a form input.
I would like to send the content of a tag from my ejs page/client to my nodejs/server.
What I'm trying...
page.ejs
<div>
<form action="/brewery" method="GET">
<div class="form-group">
<input type="text" class="form-control"
placeholder="search brewery name"
name="search">
</div>
<input class="button" type="submit" value="Submit">
</form>
</div>
<div>
<ul>
<% searchBreweryList.forEach(function(searchBrewery){ %>
<div>
<li>
Brewery Name: <span><%= searchBrewery.brewery.brewery_name %></span>
Brewery ID: <span name="brewID" id="shareBreweryID"><%= searchBrewery.brewery.brewery_id %></span>
</li>
</div>
<% }) %>
</ul>
</div>
Then on my server side...
server.js
app.get('/brewery', async (req, res) => {
var searchBreweryFound = req.query.search;
var isIndie = req.params.brewID
//console.log(isIndie)
//console.log(searchBreweryFound)
try {
request("https://api.com/v4/search/brewery?access_token=abc123&limit=1&q=" + searchBreweryFound, function (error, response, body)
{
if (error) throw new Error(error);
const searchBrewery = JSON.parse(body);
const searchBreweryList = searchBrewery.response.brewery.items.map(item => item );
res.render('brewery.ejs', {searchBreweryList});
//console.log(searchBreweryList);
});
} catch(e) {
console.log("Something went wrong", e)
}
});
So the above Get call is just an example where I'm trying to take the result in the client side span that looks like <span name="brewID">. Then I'm trying to give that ID number to the server in the var seen as var isIndie = req.params.brewID.
But this does not seem to be a method that allows me to pass content from a span in client to server.
What approach should I be taking? Thanks!
It's not clear what you mean by "sending data from client to server". Standard method of sending data from client to server is using XMLHttpRequest (XHR) inside *.js file(s), but based on your code you want to redirect browser window to URL with some parameters. When browser hit your endpoint, for example /brewery, server will render *.ejs file and respond to browser with HTML code.
Redirecting browser with EJS
Below code is based on code you posted.
<div>
<ul>
<% searchBreweryList.forEach(function(searchBrewery){ %>
<div>
<li>
Brewery Name: <span>
<%= searchBrewery.brewery.brewery_name %>
</span>
Brewery ID: <span name="brewID" id="shareBreweryID">
<%= searchBrewery.brewery.brewery_id %>
</span>
<!-- Here we create link using parameter of brewery (version with param) -->
Go to brewery
<!-- Version with query param -->
Go to brewery
</li>
</div>
<% }) %>
</ul>
</div>
After clicking Go to brewery browser will hit /brewery endpoint with param brewery_id. I also noticed that in posted example var isIndie = req.params.brewID may not work.
Bonus: req.query vs req.params
Both req.query and req.params are used to get some informations from endpoint URL. However req.query and req.params are not the same.
Using req.query
For endpoint: /brewery?id=5&q=test
const id = req.query.id // 5
const q = req.query.q // 'test'
Using req.params
To use req params you must place param name somewhere in url of express endpoint.
app.get('/brewery/:id', async (req, res) => {
var id = req.params.id
})
So to make your example with req.params working:
app.get('/brewery/:brewID', async (req, res) => {
var searchBreweryFound = req.query.search;
var isIndie = req.params.brewID
// Rest of your code
})

Express: POST does not send data - var is not defined

In a view, i am trying to get the data that a user sent, via a form, from another view.
This is the view with the form (i have omitted some EJS stuff to avoid confusion):
<form action="/renderer" method="POST" id="sc-form">
<label for="model">Choose a model:</label>
<select name="model" id="model">
<% data.forEach(function(dat) { %>
<option value="<%= dat %>"> <%= dat %> </option>
<% }); %>
</select>
<input type="submit" value="Render the model!" />
</form>
As you can see, the user selects from a dropdown, and then data is POSTed on /renderer.
So, let's handle this POST request on routes.js:
app.post('/renderer', function(req, res) {
var myModel = req.body.model;
res.render('renderer.ejs', {data: myModel});
});
Pretty basic, we get the data that the form sent and we send it to renderer.ejs as parameters.
Finally, let's grab the data on /renderer.ejs (this is inside a <script> tag):
var modelName = <%- JSON.stringify(data) %>;
And i get this error:
data is not defined
But why is that? Data is the name of the variable that the router sent to the view, as parameter.
This is the third day that i am trying to make POST data appear on another view. If anyone could help i would really appreciate it.
I finally found this.
The form has to contain role="form", or else it wouldn't work.

how make checkbox stay checked and reset in node js

I am working on a small project with checkbox and node js. I need the checked box stay on the screen after I click submit button and reset the form after clicking reset button.How can do that?
ejs code
<form method="post" action="/">
<input type="checkbox" name="preference" value="A">A
<input type="checkbox" name="preference" value="B">B
<input type="checkbox" name="preference" value="C">C
<input type="submit" value="Click to Submit">
<input type="reset" value="Erase and Restart">
</form>
node js
express.get('/', (req, res) => {
res.render('form');
});
express.post('/', (req, res) => {
console.log(req.body);
let checkedValue =req.body.preference;
let output = checkedValue==undefined?`You didn' make selection.`:`The preference iterm on menu is ${checkedValue}`;
res.render('form',{
output:output,
});
});
What's going on is that when you submit your form, the webpage is reloaded, so you lose your checked state. You can either save the values on your server and have them pre-checked using an optional checked flag in your ejs template or you can add some client side javascript to handle the form submission for you by writing and event handler for the submit event on the form.
if you expand your ejs template with a conditional checked value on your inputs, your returned page will have them pre-checked
<input type="checkbox" name="preference" <% if (submittedValue === "A") { %>checked<% } %> value="A">A
Or, here's a super simple bit of javascript that would send the values to your server
document.forms[0].addEventListener('submit', function (e) {
e.preventDefault(); // prevent the form from submitting with a page refresh
const data = { values: [] };
e.target.elements.forEach((formEl) => {
if (formEl.checked) data.values.push(formEl.value);
});
fetch('/urlToProcessYourForm', { method: 'POST', body: JSON.stringify(data) });
});

How to do conditional includes of partials in hoganjs with expressjs? (using hogan-express module)

I'm using express 3.0.x with hogan-express as template engine to build a single page application.
I would like to add a partial that will contain information that will help me to develop / debug the application. (I am also working with angularjs)
Depending on a variable somewhere in my app, like "devMode = true" I'd like to include this particular partial and it won't be included if "devMode = false".
Here are my files
index.js (routes):
exports.index = function(req, res) {
res.locals = {
template_engine: 'HoganJS'
}
return res.render(
'index',
{
partials:
{
head: 'head', foot: 'foot'
}
}
);
};
exports.partials = function(req, res) {
res.render('partials/' + req.params.entity + '/' + req.params.name)
}
index.html:
[[> head]]
<div class="navbar fixed-top">
<div class="navbar-inner">
<a class="brand" href="/">My app</a>
<ul class="nav">
</ul>
</div>
</div>
<div class="container">
<div ng-view></div>
</div>
[[> foot]]
(I changed {{ }} to [[ ]] to resolve conflict with angularjs syntax)
I'd like to include something like [[>dev]] before [[> foot]] depending on a boolean somewhere in my app.
Thank you for any help:)

Resources