Here's one for you all. FYI, this is all local right now.
I'm building a simple blog site with ejs. Every page can be called and loads perfectly...except for my post page. It stalls and then once I type 'rs' in my terminal to start it (which should clear my post array of any info), it renders! To me this makes no sense because how would it know what to render after the array has been cleared?
I've gone through the code a couple times, but I figured I would reach out to you fine people to help me out.
Any ideas?
Here is my code
...
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const _ = require("lodash");
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
//global post array
let posts =[];
//home logic
app.get("/", function (req, res) {
res.render("home", {
startingContent:homeStartingContent,
posts: posts} );
});
// about logic
app.get("/about", function (req, res) {
res.render("about", {aboutContent:aboutContent});
});
//contact logic
app.get("/contact", function (req, res) {
res.render("contact", {contactContent:contactContent});
});
//compose logic
app.get("/compose", function (req, res){
res.render("compose");
});
app.post('/compose', function(req, res) {
const postContent = {
title: req.body.postTitle,
content: req.body.postBody
};
posts.push(postContent);
res.redirect("/")
});
//Routing Parameters
app.get("/posts/:postName", function(req, res){
const requestedTitle = _.lowerCase(req.params.postName);
posts.forEach(function(post){
const storedTitle = _.lowerCase(post.title);
if (storedTitle === requestedTitle) {
res.render("post", {
title: post.title,
content: post.content
});
};
});
});
app.listen(3000, function() {
console.log("Server started on port 3000");
});
...
my post.ejs code
...
<%- include('partials/header'); -%>
<h1><%=title%></h1>
<p><%=content%></p>
<%- include('partials/footer'); -%>
..
I removed the loop from the code and instead create two constants that satisfied my requirements. This code was suggested to me by a colleague.
app.get("/posts/:postName", function (req,res) {
const requestedTitle = _.lowerCase(req.params.postName);
//Put the req.params.postName constant into a new constant instead of
putting it in a loop.
const storedTitle = posts.filter((post) => (
_.lowerCase(post.title) === requestedTitle)
);
//reroute to homepage
if (storedTitle.length === 0) {
res.redirect('/');
//otherwise render the page that was called
} else {
res.render('post', {
title: storedTitle[0].title,
content: storedTitle[0].content
})
}
})
Try to first finish the iteration and find (or not) the related post. After that, if it is not found, you still have to send something as a response:
app.get("/posts/:postName", (req, res) => {
const requestedTitle = _.lowerCase(req.params.postName);
const post = posts.find((post) => _.lowerCase(post.title) === requestedTitle);
if (post) {
res.render("post", {
title: post.title,
content: post.content
});
} else {
// of course, you must have error page for this to work
res.status(404).render("error", {
message: `Post "${requestedTitle}" not found`,
});
}
});