I am trying to learn EJS and make a blog but I cant seem to understand this error
What I am trying to do is try to write some db response as an Object to an array then push it to the file. I am using replit DB
const fs = require("fs") const Database = require("@replit/database") const db = new Database() exports.load = async function(){ db.set("hello", { "author": "Some author 1", "title": "Blog Post 1", "content": "First post content", "date_posted": "Dec 17, 2021" }) var posts = new Array() db.list().then(keys => { keys.forEach(key => { posts.push(` <article class="media content-section"> <div class="media-body"> <div class="article-metadata"> <a class="mr-2" href="/p">Anonymous</a> <small class="text-muted">${db.get(key).date_posted}</small> </div> <h2><a class="article-title" href="#">${ db.get(key).title }</a></h2> <p class="article-content">${ db.get(key).content }</p> </div> </article` ) }) }); posts = posts.join() fs.writeFileSync("public/posts.ejs", posts) }
Error that I am getting when I run the code:
UnhandledPromiseRejectionWarning: TypeError: posts.push is not a function
Advertisement
Answer
First, you declare var posts = new Array()
. So posts
is an array. Next line (in execution order) : posts = posts.join()
. So now posts
is an empty string. You are changing the type of the variable, which is a bad practice (Typescript wouldn’t let you do that). Now next line in execution order : .then(keys =>
. You start pushing stuff into posts
, but posts
is now a string, remember? Not an array anymore.
You use the async
keyword for no reason, since there is no await
in it. You might as well leverage it :
exports.load = async function(){ db.set("hello", { "author": "Some author 1", "title": "Blog Post 1", "content": "First post content", "date_posted": "Dec 17, 2021" }) let postsArray = new Array(); const keys = await db.list(); keys.forEach(key => { postsArray.push(`<article class="media content-section"> <div class="media-body"> <div class="article-metadata"> <a class="mr-2" href="/p">Anonymous</a> <small class="text-muted">${db.get(key).date_posted}</small> </div> <h2><a class="article-title" href="#">${ db.get(key).title }</a></h2> <p class="article-content">${ db.get(key).content }</p> </div> </article` ) }) const posts = postsArray.join() fs.writeFileSync("public/posts.ejs", posts) }
OR with .map() in one line :
exports.load = async function(){ db.set("hello", { "author": "Some author 1", "title": "Blog Post 1", "content": "First post content", "date_posted": "Dec 17, 2021" }) const keys = await db.list(); const posts = keys.map( key => `<article class="media content-section">....</article`).join(); fs.writeFileSync("public/posts.ejs", posts) }