i have this problem sorting my object of data in my index of my blog app.
I have a blog app based on Express using ejs and mongoDB using mongoose.
What i want is sorting the results so the newest post starts at the top. At this moment it will show the first post at the top.
app.js / mongoose schema
blogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {type: Date, default: Date.now}
});
var Blog = mongoose.model("Blog", blogSchema);
app.js / Index route
app.get("/blogs", (req, res)=>{
Blog.find({}, (err, blogs)=>{
if(err){
console.log("Error!");
console.log(err);
} else {
res.render("index", {blogs: blogs});
}
});
});
index.ejs foreach
<% blogs.forEach(function(blog){ %>
<img alt="img" src="<%= blog.image %>">
<%= blog.title %>
<span><%= blog.created.toDateString() %></span>
<p><%- blog.body.substring(0, 200) %>...</p>
Read More
<% }) %>
Does anyone have a clue how i can do this?
You can use the sort() method of Mongoose:
Blog.find((err, blogs) => {
if (err) {
console.log(err);
} else {
res.render("index", { blogs: blogs });
}
}).sort({ created: 'desc' });
Related
I want to fetch all the users in my db inside my ejs file. I have 3 files one model for the data, one ejs file and one js file for my route. The problem is that I don't have any error displaying. I just have an empty list rendered on my browser as if there was no users in the database. Can someone help me?
Here is my route js file :
import express from 'express';
import User from "../models/user.js"
const routerUserList = express.Router();
routerUserList.get('/user-list', function(req, res, next) {
try {
const users = User.find({});
res.render('user-list', {
pageTitle: 'Liste des utilisateurs',
path: '/user-list',
users: users
})
} catch (error) {
res.status(500).json({message : "Une erreur est survenue"})
}
})
export default routerUserList
Here is my ejs file :
<%- include('./includes/head.ejs') %>
</head>
<body>
<%- include('./includes/navigation.ejs') %>
<main>
<h1>Liste des utilisateurs</h1>
<% for(var i=0; i < users.length; i++) {%>
<li><%= users[i]._id %></li>
<li><%= users[i].name %></li>
<li><%= users[i].email %></li>
<% } %>
</main>
<%- include('./includes/end.ejs') %>
Here is my model file :
import mongoose from 'mongoose'
const userSchema = mongoose.Schema({
name: {type: String, required: true},
email: {type: String, required: true},
password: {type: String, required: true},
id: {type: String}
})
export default mongoose.model("User", userSchema)
mongoose model always returns Promise, you should resolve this promise to get an actual array of users.
Updated code will look like this.
import express from 'express';
import User from "../models/user.js"
const routerUserList = express.Router();
routerUserList.get('/user-list', async function(req, res, next) {
try {
const users = await User.find({});
res.render('user-list', {
pageTitle: 'Liste des utilisateurs',
path: '/user-list',
users: users
})
} catch (error) {
res.status(500).json({message : "Une erreur est survenue"})
}
})
export default routerUserList
My PostSchema is like this:
let PostSchema = new mongoose.Schema({
content: String,
time: Date,
likes: Number,
image: String,
tag: String
});
let Post = mongoose.model("Post", PostSchema);
module.exports = Post;
And I'd like to get a list of all the posts with the same tag
Here is my code to get it rendered. It is in the folder routes/post
router.get("/tag", function(req, res) {
Post.find({ subreddit: req.params.tag }).lean()
.then(posts => {
res.render("posts/index", { posts });
})
.catch(err => {
console.log(err);
});
});
Of course I have the views/posts folder with index.ejx to route the view
<li class="list-group-item">
<div class="text-right">
<span>Tags: </span><%= post.tag %>
</div>
</li>
I don't really understand how or where I got it wrong. I tried to follow the instruction of the tutorial here: https://www.makeschool.com/academy/track/standalone/reddit-clone-in-node-js/create-subreddits
Maybe try to trim the value you search:
router.get("/tag", function(req, res) {
let tag = req.params.tag;
if (!tag) {
throw new Error('No tag was found');
}
tag = tag.trim();
Post.find({ subreddit: req.params.tag }).lean()
.then(posts => {
res.render("posts/index", { posts });
})
.catch(err => {
console.log(err);
});
});
When I add a comment to any blog post it doesn't work. This is a normal Node.js MVC controller which is linked to route:
commentBlog(req, res) {
const comment = {
comment: req.body.comment,
author: req.params.id
}
Comment.create(comment, (error, comment) => {
if (error) {
console.log(error);
} else {
Blog.findById(req.params.id, (error, blog) => {
blog.comments.push(comment);
console.log(comment);
blog.save((error, savedBlog) => {
if (error) {
console.log(error);
} else{
res.redirect('/blogs/' + blog._id);
}
})
})
}
})
};
( this is the model )
--------------------
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
var commentSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'user' },
comment: {type: String},
created: {type: Date, default: Date.now},
blog: { type: Schema.Types.ObjectId, ref: 'blog' }
});
var Comment = mongoose.model('comment', commentSchema);
module.exports = Comment;
this is the ejs file
---------------------
<body>
<% if(blog) { %>
<form action="/blogs/<%= blog._id %>/comment" method="POST">
<textarea name="comment[text]"
rows="10" cols="50">Write something here
</textarea>
<input type="submit" value="Post comment">
</form>
<% } %>
**i don't know why it doesn't display when i add like to any post it just
don't work**
Well, you were not displaying the blog content in your ejs file. Only rendering the form. You should render the blog fields for them to display. Below is an example to show the blog title( provided there is a title field in the blog object).
<body>
<% if(blog) { %>
<h2><%= blog.title %> </h2>
<form action="/blogs/<%= blog._id %>/comment" method="POST">
<textarea name="comment[text]"
rows="10" cols="50">Write something here
</textarea>
<input type="submit" value="Post comment">
</form>
<% } %>
You can then display the other fields in your blog object using the example above.
I am trying to loop my database collections based on a parameter request for one of my schema properties within a view. I have a tags property within my schema that is saved as an array. What I want to be able to do is click on one of the values saved to that array, which will render a page with collections that contain the selected tags value. I have been able to create the route, which will direct me to the individual tag that was clicked, but I receive a tags: [xxx, xxx, xxx] has no method .forEach.that occurs when I call my loop within my view. Why would this be and how should I solve this?
Error message:
TypeError: /Users/user/Desktop/Projects/node/blog/views/pages/tag.ejs:15
13| <div class="col-md-12">
14| <h1><%= blogpost.tags %></h1>
>> 15| <% blogpost.forEach(function(blogpost) { %>
16| <%= blogpost.title %>
17| <% }); %>
18| </div>
Object { _id: 54c7bd20c58f389232000001,
category: 'Analytics/SEO/SEM',
content: '',
tagline: 'yep',
author: 'Author',
blogUrl: 'roger',
featureImage: '/images/event-placeholder.png',
title: 'Roger',
__v: 0,
date: Tue Jan 27 2015 11:29:48 GMT-0500 (EST),
tags: [ 'wolf', ' cow', ' monkey' ] } has no method 'forEach'
Here is my model:
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate');
var Schema = mongoose.Schema;
var BlogPostSchema = new Schema({
title: { type: String, unique: true },
featureImage: String,
blogUrl: String,
author: String,
tagline: String,
category: String,
content: String,
tags: { type: Array, lowercase: true },
date: { type: Date, default: Date.now() }
});
BlogPostSchema.post('init', function (post) {
var date = new Date(post.date || Date.now() );
post.dateString = date.getMonth() + 1 + '/' + date.getDate() + '/' + date.getFullYear();
});
BlogPostSchema.plugin( mongoosePaginate );
var Blogpost = mongoose.model("Blogpost", BlogPostSchema);
module.exports = mongoose.model('Blogpost', BlogPostSchema);
Here is how I'm calling my individually selected tag within my route (Does my function use the correct parameter call method?):
router.route('/admin/posts/create')
// START POST method
.post(function(req, res) {
console.log("New instance");
console.log(req.body.tags);
var blogpost = new Blogpost(); // create a new instance of a Blogpost model
blogpost.title = req.body.title; // set the blog title
blogpost.featureImage = req.body.featureImage; // set the blog image
blogpost.blogUrl = blogpost.title.toLowerCase().replace(/\s+/g,"-");
blogpost.author = req.body.author; // set the author name
blogpost.tagline = req.body.tagline; // set the tagline
blogpost.content = req.body.content; // set the blog content
blogpost.category = req.body.category; // set the category
blogpost.tags = req.body.tags.trim().split(","); // set the tags
//Save Blog Post
blogpost.save(function(err) {
if (err)
res.send(err);
res.redirect(303, '/'); //NEEDS TO BE CHANGED
});
}) // END POST method
.get(isLoggedIn, function(req, res, blogpost) {
res.render('pages/blogpost-create', {
blogpost : blogpost
});
});
function getTagCriteria(params){
return {
tags: params.blogpost_tags
};
}
router.route('/tag/:blogpost_tags')
.get(function (req, res) {
var tagCriteria = getTagCriteria(req.params);
Blogpost.findOne(tagCriteria, function (err, blogpost) {
if (err)
res.sent(err);
res.render('pages/tag', {
blogpost : blogpost
})
})
});
pages/tag view file:
<div class="container">
<div class="col-md-12">
<h1><%= blogpost.tags %></h1>
<% blogpost.forEach(function(blogpost) { %>
<%= blogpost.title %>
<% }); %>
</div>
</div>
Change your mongo query to:
Blogpost.find(tagCriteria, function (err, blogpost) {
if (err)
res.sent(err);
res.render('pages/tag', {
blogpost : blogpost
})
})
NOTE: blogpost will now be an array [] instead of an object {}
Then in your jade, do the following
<% blogpost.forEach(function(post) { %>
<%= post.title %>
<% }); %>
I am trying to use the mongoose-paginate and express-paginate as advised on both GitHub repositories. I have set up the mongoose-paginate in my model and have the correct response, but can't seem to figure out how to use the express-paginate within my routes and view. I have 11 or 12 entries in my database and it picks up correctly to create a second page, but it isn't finding paginate in my view file.
Right response from model setup:
Pages: 2
[ { content: 'maybe not',
author: 'Connor John',
title: 'This is the 11 test',
_id: 540487ddc787d60000000009,
__v: 0,
date: Thu Sep 04 2014 19:48:02 GMT-0400 (EDT) } ]
blogModel.js (using mongoose-paginate):
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate');
var Schema = mongoose.Schema;
var BlogPostSchema = new Schema({
title: String,
author: String,
content: String,
date: { type: Date, default: Date.now }
});
BlogPostSchema.plugin( mongoosePaginate );
var Blogpost = mongoose.model("Blogpost", BlogPostSchema);
Blogpost.paginate({}, 2, 10, function(err, pageCount, blogpost, count) {
if (err) {
console.error(error);
} else {
console.log('Pages:', pageCount);
console.log(blogpost);
}
});
module.exports = mongoose.model('Blogpost', BlogPostSchema);
routes.js (express-paginate):
var express = require('express');
var app = express();
var router = express.Router();
var blogDB = require('../config/blogDB.js');
var Blogpost = require('./models/blogModel.js');
var paginate = require('express-paginate');
//index
router.route('/')
.get(function(req, res) {
var drinks = [
{ name: 'Bloody Mary', drunkness: 3 },
{ name: 'Martini', drunkness: 5 },
{ name: 'Scotch', drunkness: 10}
];
var tagline = "Lets do this.";
res.render('pages/index', {
drinks: drinks,
tagline: tagline
});
});
app.use(paginate.middleware(10, 50));
//blog
router.route('/blog')
// START POST method
.post(function(req, res) {
var blogpost = new Blogpost(); // create a new instance of a Blogpost model
blogpost.title = req.body.title; // set the blog title
blogpost.author = req.body.author; // set the author name
blogpost.content = req.body.content; // set the blog content
blogpost.date = req.body.date; // set the date of the post
//Save Blog Post
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog created.' });
});
}) // END POST method
// START GET method
.get(function(req, res, next) {
Blogpost.paginate({}, req.query.page, req.query.limit, function(err, pageCount, blogpost, itemCount) {
if (err) return next(err)
Blogpost.find(function(err, blogpost) {
if (err)
res.send(err);
blogpost.title = req.body.title; // update the blog title
blogpost.author = req.body.author; // set the author name
blogpost.content = req.body.content; // update the blog content
blogpost.date = req.body.date; // set the date of the post
res.format({
html: function() {
res.render('pages/blog', {
blogpost: blogpost,
pageCount: pageCount,
itemCount: itemCount
})
},
json: function() {
res.json({
object: 'blogpost',
has_more: paginate.hasNextPages(req)(pageCount),
data: blogpost
})
}
});
}) //END Find Blogpost
}); // END GET method
//Route for individual blogs
router.route('/blog/:blogpost_id')
// START GET method blog by ID
.get(function(req, res) {
Blogpost.findById(req.params.blogpost_id, function(err, blog) {
if (err)
res.send(err);
res.json(blog);
});
}) // END GET method blog by ID
// START PUT method
.put(function(req, res) {
Blogpost.findById(req.params.blogpost_id, function(err, blogpost) {
if (err)
res.send(err);
blogpost.title = req.body.title; // update the blog title
blogpost.author = req.body.author; // set the author name
blogpost.content = req.body.content; // update the blog content
blogpost.date = req.body.date; // set the date of the post
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
});
}) // END PUT method
// START DELETE method
.delete(function(req, res) {
Blogpost.remove({
_id: req.params.blogpost_id
}, function(err, bear) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
}); //END Paginate
//about
router.get('/about', function(req, res) {
res.render('pages/about');
});
module.exports = router;
paginate.ejs (express-paginate):
<div class="grid">
<div class="col-1-1">
<div class="paginate">
<ul>
<% if (paginate.hasPreiousPages) { %>
<li>
Previous
</li>
<% } %>
<% if (paginate.hasNextPages) { %>
<li>
Next
</li>
<% } %>
</ul>
</div>
</div>
</div>
blog.ejs (express-paginate):
<html>
<head>
<% include ../partials/head %>
</head>
<body>
<header>
<% include ../partials/header %>
</header>
<div class="grid">
<div class="col-1-1">
<div class="body-content">
<% blogpost.forEach(function(blogpost) { %>
<tr>
<td><h2><%= blogpost.title %></h2></td>
<td><h3><%= blogpost.author %></h3></td>
</tr>
<% }); %>
</div>
</div>
</div>
<div class="paginate">
<% include ../partials/paginate %>
</div>
<footer>
<% include ../partials/footer %>
</footer>
</body>
</html>
error message:
ReferenceError: /Users/user/Desktop/Projects/node/blog/views/pages/blog.ejs:7
5|
6| <body>
>> 7|
8| <header>
9| <% include ../partials/header %>
10| </header>