Why is my JS logic appearing on index (using ejs/express) - node.js

im having an issue understanding why my JS is appearing on my layout. Im currently following along with a tutorial on sitepoint creating forms with in express and when i render the layout.ejs + index.ejs with contact as a partial, the logic on partial is appearing on the page as text.
here is the code:
<div class="form-header">
<% if (Object.keys(errors).length === 0) { %>
<h2>Send us a message aa</h2>
<% } else { %>
<h2 class="errors-heading">Oops, please correct the following:</h2>
<ul class="errors-list">
<% Object.values(errors).forEach(error => { %>
<li><%= error.msg %></li>
<% }) %>
</ul>
<% } %>
</div>
<form method="post" action="/contact" novalidate>
<div class="form-field <%= errors.message ? 'form-field-invalid' : ''
%>">
<label for="message">Message</label>
<textarea class="input" id="message" name="message" rows="4"
autofocus><%= data.message %></textarea>
<% if (errors.message) { %>
<div class="error"><%= errors.message.msg %></div>
<% } %>
</div>
<div class="form-field <%= errors.email ? 'form-field-invalid' : '' %>">
<label for="email">Email</label>
<input class="input" id="email" name="email" type="email" value="<%=
data.email %>" />
<% if (errors.email) { %>
<div class="error"><%= errors.email.msg %></div>
<% } %>
</div>
<div class="form-actions">
<button class="btn" type="submit">Send</button>
</div>
</form>

Related

Why is my ejs outputting the actual html code and not rendering it as html?

I am doing some simple validation on a form and using bootstrap for alert dismissing. I have an ejs partial for displaying error messages. When trying to render the error message its just showing the actual block of code.
Here is my partials ejs:
<% if(typeof errors != 'undefined') { %>
<% errors.forEach(error => { %>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<%= error.msg %>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<% }) %>
<% } %>
Here is where I include that partial to the register.ejs file I have
<%= include ("./partials/messages") %>
<form action="/users/register" method="POST">
<div class="form-group">
<label for="name">Name</label>
<input
type="name"
id="name"
name="name"
class="form-control"
placeholder="Enter Name"
value="<%= typeof name != 'undefined' ? name : '' %>"
/>
Here is a screenshot of what it is outputting:
Why is it showing the actual code instead of rendering as HTML?

Crud app API POST error, not able to find the issue

Making a crud app with Node and Mongo.
While updating a user the API is not able to POST the data and returning an error in the browser Cannot POST /update-user
I am able to add a user, but while updating the user it is returning an error.
This is my Add user page:
<!-- include header -->
<%- include('include/_header') %>
<!-- /include header -->
<!--Main site-->
<main id="site-main">
<div class="container">
<div class="box-nav d-flex justify-between">
<div class="filter">
<i class='fas fa-angle-double-left'></i>All Users
</div>
</div>
<div class="form-title text-center">
<h2 class='text-dark'>New User</h2>
<span class='text-light'>Use the form below to create a new account</span>
</div>
<!-- add user form -->
<%- include('include/_form') %>
</div>
</main>
<!--Main site-->
<!-- include footer -->
<%- include('include/_footer') %>
<!-- /include footer -->
This is the footer:
<script src="<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="../../assets/js/index.js"></script>
</body>
</html>
This is the Index.js connected to the footerL:
$("#add_user").submit(function(event){
alert("Data inserted successfully");
})
$("#update_user").submit(function(event){
event.preventDefault();
var unindexed_array = $(this).serializeArray();
var data = {}
$.map(unindexed_array, function(n, i){
data[n['name']] = n['value']
})
})
This is the index.js connected to the footer:
$("#add_user").submit(function(event){
alert("Data inserted successfully");
})
$("#update_user").submit(function(event){
event.preventDefault();
var unindexed_array = $(this).serializeArray();
var data = {}
$.map(unindexed_array, function(n, i){
data[n['name']] = n['value']
})
})
This is the Update user form:
<!-- include header -->
<%- include('include/_header') %>
<!-- /include header -->
<!-- Main Site -->
<main id="site-main">
<div class="container">
<div class="box-nav d-flex justify-between">
<div class="filter">
<i class="fas fa-angle-double-left"></i> All Users
</div>
</div>
<div class="form-title text-center">
<h2 class="text-dark">Update User</h2>
<span class="text-light">Use the below form to Update an account</span>
</div>
<!-- add user form -->
<!-- form handling -->
<form method="POST" id="update_user">
<div class="new_user">
<div class="form-group">
<label for="name" class="text-light">Name</label>
<input type="hidden" name="id" value="<%= user._id %>">
<input type="text" name="name" value="<%= user.name %>" placeholder="Mark Stoenis">
</div>
<div class="form-group">
<label for="Email" class="text-light">Email</label>
<input type="text" name="email" value="<%= user.email%>" placeholder="example#gmail.com">
</div>
<div class="form-group">
<label for="gender" class="text-light">Gender</label>
<div class="radio inline">
<input type="radio" id="radio-2" name="gender" value="Male" <%= user.gender == 'Male' ? 'checked' : '' %>>
<label for="radio-2" class="radio-label">Male</label>
</div>
<div class="radio inline">
<input type="radio" id="radio-3" name="gender" value="Female" <%= user.gender == 'Female' ? 'checked' : '' %> >
<label for="radio-3" class="radio-label">Female</label>
</div>
</div>
<div class="form-group">
<label for="gender" class="text-light">Status</label>
<div class="radio inline">
<input type="radio" id="radio-4" name="status" value="Active" <%= user.status == 'Active' ? 'checked' : '' %> >
<label for="radio-4" class="radio-label">Active</label>
</div>
<div class="radio inline">
<input type="radio" id="radio-5" name="status" value="Inactive" <%= user.status == 'Inactive' ? 'checked' : '' %> >
<label for="radio-5" class="radio-label">Inactive</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn text-dark update">Save</button>
</div>
</div>
</form>
</div>
</main>
<!-- /Main Site -->
<!-- include footer -->
<%- include('include/_footer') %>
<!-- /include footer -->

getting error in EJS file while running res.render

getting this error:
missing ) after argument list in C:\Users\yoniy\Desktop\YelpCamp\views\campgrounds\index.ejs while compiling ejs
and it's the index.ejs file :
<!-- <%- include "../partials/header" %> -->
<header class="jumbotron">
<div class="container">
<h1><span class="glyphicon glyphicon-tent"></span> Welcome To YelpCamp!</h1>
<p>View campgrounds from all over the world</p>
<p>
<a class="btn btn-primary btn-lg" href="/campgrounds/new">Add New Campground</a>
</p>
<p>
<form action="/campgrounds" method="GET" class="form-inline" id="campground-search">
<div class="form-group">
<input type="text" name="search" placeholder="Campground search..." class="form-control">
</div>
</form>
</p>
</div>
</header>
<div class="row text-center flex-wrap" id="campground-grid">
<%- campgrounds.forEach(function(campground){ %>
<div class="col-md-3 col-sm-6">
<div class="thumbnail">
<img src="<%= campground.image %>">
<div class="caption">
<h4><%= campground.name %></h4>
</div>
<p>
More Info
</p>
</div>
</div>
<%- }); %>
</div>
<!-- <%- include "../partials/footer" %> -->
can't find the syntax error that I get.
thanks for help !
You need to use flow control tags <% for non output parts of your template. In this case the following lines need to be changed:
<%- campgrounds.forEach(function(campground){ %>
Should instead be:
<% campgrounds.forEach(function(campground){ %>
And this line:
<%- }); %>
Should be:
<% }); %>
Update for additional Error
Your formatting for including additional files is incorrect:
<!-- <%- include "../partials/header" %> -->
Should be:
<%- include("../partials/header.ejs") %>
Same for the footer:
<!-- <%- include "../partials/footer" %> -->
Should be:
<%- include("../partials/footer.ejs") %>
Though I cannot validate your paths are correct as I do not know your directory structure.

Cannot read property 'forEach' of undefined node.js

I am getting a .forEach() error on this code
```<% if(locals.isAuthenticated) { %>
<section>
<h4>Leave a comment</h4>
<form method="POST" action="/landmarks/<%= landmark.id %>/comments">
<textarea name="content" id="content" placeholder="Comment"></textarea>
<button class="button">Leave a comment</button>
</form>
</section>
<% } %>
<section>
<h4>Comments</h4>
<% landmark.comments.forEach((comment) => { %>
<p><%= comment.content %></p>
<small><%= comment.createdBy.username %></small>
<small><%= comment.createdAt.toDateString() %></small>
<% if(locals.isAuthenticated && comment.belongsTo(user)) { %>
<form method="POST" action="/landmarks/<%= landmark.id %>/comments/<%= comment.id %>">
<input type="hidden" name="_method" value="DELETE">
<button class="btn">Delete Comment</button>
</form>
<% } %>
<% }) %>
</section>```
I am unsure why this is happening as I i believe this is correct syntax for the forEach method

showing MongoDB document value to EJS in a loop

I'm working on a node project. And node is very new to me so sorry if I ask a lot of stupid questions.
I'm trying to show all of my topics on my index.ejs. The root file already shows them in the console log but I can't seem to get them to show in the view.
The view already loops and knows that there are 2 topics, but the content is empty.
This is my code from the routes/index.js
router.get('/', function(req, res, next) {
Topic.find({}).exec(function(err, topic)
{
if(err){
console.log('There ware no topics');
return next(err)
}
else
{
console.log('Whoop whoop there are some topics');
res.render('index', { topic: topic } );
console.log("Logging data: " + topic);
console.log("Loggin data title out db: " + topic.topicTitle);
console.log("Loggin data desc out db: " + topic.topicDescription);
console.log("Loggin data date out db: " + topic.topicDateCreated);
}
});
});
module.exports = router;
And here is how I try to show it in my views/index.ejs
<ul>
<% for(var i = 0; i < topic.length; i++) {%>
<li>
<div class="post animated fadeInLeft">
<div class="wrap-ut pull-left">
<div class="userinfo pull-left">
<div class="avatar">
<img src="images/avatar.jpg" alt="default avatar" />
<p class="moderator"> <%= topic.fbUsername %> </p>
</div>
</div>
<div class="posttext pull-left">
<h2 class="topictitle"><a href="/topicdetail/{topic_id}" <%= topic.topicTitle %> </a></h2>
</div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
</li>
<% } %>
</ul>
The topic variable is an array, so you need to pass the index in order to get the proper Topic document. For instance:
<%= topic[i].fbUsername %>
Your view should look like:
<ul>
<% for(var i = 0; i < topic.length; i++) {%>
<li>
<div class="post animated fadeInLeft">
<div class="wrap-ut pull-left">
<div class="userinfo pull-left">
<div class="avatar">
<img src="images/avatar.jpg" alt="default avatar" />
<p class="moderator"> <%= topic[i].fbUsername %> </p>
</div>
</div>
<div class="posttext pull-left">
<h2 class="topictitle"> <%= topic[i].topicTitle %> </h2>
</div>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
</li>
<% } %>
</ul>
UPDATE
You also forgot to close the tag here:
--------------------------------------------------------↴
<h2 class="topictitle"><a href="/topicdetail/{topic_id}" <%= topic[i].topicTitle %> </a></h2>
Closing the tag, I was able to see the titles:
<h2 class="topictitle"> <%= topic[i].topicTitle %> </h2>

Resources