I’ve encountered a problem: posts by the author aren’t showing up for me. I recently bought a course on JavaScript and have been studying it, but I’m stuck on lesson 82 and can’t move forward.
What could be the issue in the code? I’ve done everything as the author does, but still, the posts aren’t showing up for me.
Here is the code from profile.ejs
<%- include('includes/header') %>
<div class="container py-md-5 container--narrow">
<h2><img class="avatar-small" src="<%= profileAvatar %>"> <%= profileUsername %>
<form class="ml-2 d-inline" action="#" method="POST">
<button class="btn btn-primary btn-sm">Follow <i class="fas fa-user-plus"></i></button>
<!-- <button class="btn btn-danger btn-sm">Stop Following <i class="fas fa-user-times"></i></button> -->
</form>
</h2>
<div class="profile-nav nav nav-tabs pt-2 mb-4">
<a href="#" class="profile-nav-link nav-item nav-link active">Posts: 3</a>
<a href="#" class="profile-nav-link nav-item nav-link ">Followers: 3</a>
<a href="#" class="profile-nav-link nav-item nav-link ">Following: 2</a>
</div>
<div class="list-group">
<% posts.forEach(function(post) { %>
<a href="/post/<%= post._id %>" class="list-group-item list-group-item-action">
<img class="avatar-tiny" src="<%= post.author.avatar %>">
<strong><%= post.title %></strong> on <%= post.createdDate.getMonth() + 1 %>/<%= post.createdDate.getDate() %>/<%= post.createdDate.getFullYear() %>
</a>
<% }) %>
</div>
</div>
<%- include('includes/footer') %>
And this is model/Post.js
const postsCollection = require('../db').db().collection("posts")
const ObjectId = require('mongodb').ObjectId
const User = require('./User')
let Post = function(data, userid) {
this.data = data
this.errors = []
this.userid = userid
}
Post.prototype.cleanUp = function() {
if (typeof(this.data.title) != "string") {this.data.title = ""}
if (typeof(this.data.body) != "string") {this.data.body = ""}
// get rid of any bogus properties
this.data = {
title: this.data.title.trim(),
body: this.data.body.trim(),
createdDate: new Date(),
author: ObjectId(this.userid)
}
}
Post.prototype.validate = function() {
if (this.data.title == "") {this.errors.push("You must provide a title.")}
if (this.data.body == "") {this.errors.push("You must provide post content.")}
}
Post.prototype.create = function() {
return new Promise((resolve, reject) => {
this.cleanUp()
this.validate()
if (!this.errors.length) {
// save post into database
postsCollection.insertOne(this.data).then(() => {
resolve()
}).catch(() => {
this.errors.push("Please try again later.")
reject(this.errors)
})
} else {
reject(this.errors)
}
})
}
Post.reusablePostQuery = function(uniqueOperations) {
return new Promise(async function(resolve, reject) {
let aggOperations = uniqueOperations.concat([
{$lookup: {from: "users", localField: "author", foreignField: "_id", as: "authorDocument"}},
{$project: {
title: 1,
body: 1,
createdDate: 1,
author: {$arrayElemAt: ["$authorDocument", 0]}
}}
])
let posts = await postsCollection.aggregate(aggOperations).toArray()
// clean up author property in each post object
posts = posts.map(function(post) {
post.author = {
username: post.author.username,
avatar: new User(post.author, true).avatar
}
return post
})
resolve(posts)
})
}
Post.findSingleById = function(id) {
return new Promise(async function(resolve, reject) {
if (typeof(id) != "string" || !ObjectId.isValid(id)) {
reject()
return
}
let posts = await Post.reusablePostQuery([
{$match: {_id: ObjectId(id)}}
])
if (posts.length) {
console.log(posts[0])
resolve(posts[0])
} else {
reject()
}
})
}
Post.findByAuthorId = function(authorId) {
return Post.reusablePostQuery([
{$match: {author: authorId}},
{$sort: {createdDate: -1}}
])
}
module.exports = Post
And this is controller/userController.js
const User = require('../models/User')
const Post = require('../models/Post')
exports.mustBeLoggedIn = function(req, res, next) {
if (req.session.user) {
next()
} else {
req.flash("errors", "You must be logged in to perform that action.")
req.session.save(function() {
res.redirect('/')
})
}
}
exports.login = function(req, res) {
let user = new User(req.body)
user.login().then(function(result) {
req.session.user = {avatar: user.avatar, username: user.data.username, _id: user.data._id}
req.session.save(function() {
res.redirect('/')
})
}).catch(function(e) {
req.flash('errors', e)
req.session.save(function() {
res.redirect('/')
})
})
}
exports.logout = function(req, res) {
req.session.destroy(function() {
res.redirect('/')
})
}
exports.register = function(req, res) {
let user = new User(req.body)
user.register().then(() => {
req.session.user = {username: user.data.username, avatar: user.avatar, _id: user.data._id}
req.session.save(function() {
res.redirect('/')
})
}).catch((regErrors) => {
regErrors.forEach(function(error) {
req.flash('regErrors', error)
})
req.session.save(function() {
res.redirect('/')
})
})
}
exports.home = function(req, res) {
if (req.session.user) {
res.render('home-dashboard')
} else {
res.render('home-guest', {errors: req.flash('errors'), regErrors: req.flash('regErrors')})
}
}
exports.ifUserExists = function(req, res, next) {
User.findByUsername(req.params.username).then(function(userDocument) {
req.profileUser = userDocument
next()
}).catch(function() {
res.render("404")
})
}
exports.profilePostsScreen = function(req, res) {
// ask our post model for posts by a certain author id
Post.findByAuthorId(req.profileUser._id).then(function(posts) {
res.render('profile', {
posts: posts,
profileUsername: req.profileUser.username,
profileAvatar: req.profileUser.avatar
})
}).catch(function() {
res.render("404")
})
}
And this is router.js
const express = require ('express')
const router = express.Router()
const userController = require ('./controllers/userController')
const postController = require ('./controllers/postController')
// user related routes
router.get('/', userController.home)
router.post('/register',userController.register)
router.post('/login', userController.login)
router.post('/logout', userController.logout)
// profile related routes
router.get('/profile/:username', userController.ifUserExists, userController.profilePostsScreen)
// post related routes
router.get('/create-post', userController.mustBeLoggedIn, postController.viewCreateScreen)
router.post('/create-post', userController.mustBeLoggedIn, postController.create)
router.get('/post/:id', postController.viewSingle)
module.exports = router
I hope someone can help me with this.
I did the same thing like author did, I copied the whole code from the original source and past it but still the same problem