I am trying to use the PUT method to update a record in my database, but I am running into a issue where the object is not defined.
ReferenceError: blogpost is not defined
I am referencing this tutorial with my routing steps and noticed that despite the variable being defined in my /blogs route, meaning that it is local to that function, that in the tutorial, they don't define the variable again when routing their put method. They simply call the object's property that they plan to update. Is there a reason why I'm not able to access this object? Is it a scope issue?
routes.js:
var express = require('express');
var router = express.Router();
var blogDB = require('../config/blogDB.js');
var Blogpost = require('./models/blogModel.js');
//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
});
});
//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.content = req.body.content; // set the blog content
//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) {
Blogpost.find(function(err, blogs) {
if (err)
res.send(err);
res.json(blogs);
});
}); // 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, blog) {
if (err)
res.send(err);
blogpost.title = req.body.title; // update the blog title
blogpost.content = req.body.content; // update the blog content
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
});
});
//about
router.get('/about', function(req, res) {
res.render('pages/about');
});
module.exports = router;
Specific area where the issue is created:
// START PUT method
.put(function(req, res) {
Blogpost.findById(req.params.blogpost_id, function(err, blog) {
if (err)
res.send(err);
blogpost.title = req.body.title; // update the blog title
blogpost.content = req.body.content; // update the blog content
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
});
});
Blogpost.findById(req.params.blogpost_id, function(err, blog) {
Should be:
Blogpost.findById(req.params.blogpost_id, function(err, blogpost) {
Related
I keep getting this error below after posting a form using expressjs and a dust template. The form is meant to redirect after posting.
The main error lies around the router.post section it seems the problem only occurs after I try to redirect using res.redirect.
VError: Problem rendering dust template "C:\Users\USER\Desktop\nodejs\Node-Bookstore\public\templates\manage\books\add.dust": The "path" argument must be of type string. Received an instance of Chunk
at Stub.callback (C:\Users\USER\Desktop\nodejs\Node-Bookstore\node_modules\adaro\lib\engine.js:167:30)
at Stub.flush (C:\Users\USER\Desktop\nodejs\Node-Bookstore\node_modules\dustjs-linkedin\lib\dust.js:564:14)
at Chunk.setError (C:\Users\USER\Desktop\nodejs\Node-Bookstore\node_modules\dustjs-linkedin\lib\dust.js:1051:15)
at C:\Users\USER\Desktop\nodejs\Node-Bookstore\node_modules\dust-usecontent-helper\index.js:25:27
at C:\Users\USER\Desktop\nodejs\Node-Bookstore\node_modules\dust-makara-helpers\index.js:50:21
at C:\Users\USER\Desktop\nodejs\Node-Bookstore\node_modules\iferr\index.js:13:50
at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)
It only happens after res.redirect()
My code:
'use strict';
var Book = require('../models/bookmodel');
var Category = require('../models/categorymodel');
module.exports = function (router) {
router.get('/', function (req, res){
res.render('manage/index');
});
// Get Books
router.get('/books', function (req, res){
Book.find({},{}, function (err, books){
if (err){
console.log(err);
}
var model = {
books: books
}
res.render('manage/books/index', model);
});
});
// Get add book
router.get('/books/add', function (req, res){
Category.find({},{}, function (err, categories){
if (err){
console.log(err);
}
var model = {
categories: categories
}
console.log("before rendered manage/books/add");
res.render('manage/books/add', model);
});
});
//Post the details from the add books page!
router.post('/books', function (req, res){
var title = req.body.title && req.body.title.trim();
var category = req.body.category && req.body.category.trim();
var author = req.body.author && req.body.author.trim();
var publisher = req.body.publisher && req.body.publisher.trim();
var price = req.body.price && req.body.price.trim();
var description = req.body.description && req.body.description.trim();
var cover = req.body.cover && req.body.cover.trim();
if (title == '' || price == "") {
req.flash('error', 'Please input the price and title');
res.location('/manage/books/add');
res.redirect('/manage/books/add');
console.log("Empty title or price");
}
else if (isNaN(price)) {
req.flash('error', 'Price must be a number!');
res.location('/manage/books/add');
res.redirect('/manage/books/add');
console.log("price is NaN");
}else {
var newBook = new Book({
title: title,
category: category,
description: description,
author: author,
publisher: publisher,
cover: cover,
price: price,
});
newBook.save(function(err){
if (err){
console.log('save failed: ', err);
}
req.flash('success', 'New Book Added!');
res.location('/manage/books');
res.redirect('/manage/books');
console.log("was able to redirect");
});
}
});
router.get('/categories', function (req, res){
res.render('manage/categories/index');
});
};
Note: There is nothing wrong with the add.dust file
For some reason req.flash() was the issue here. Apparently I can't use the same syntax used in Jade with Dust
This will be added to the main index.js file in your root folder where you initialised the middel-ware for connect-flash
app.use(flash());
app.use(function (req, res, next) {
var messages = require('express-messages')(req, res);
res.locals.messages = function (chunk, context, bodies, params) {
return chunk.write(messages());
};
next();
});
Note that the messages function asks for (chunk, context, bodies, params) parameters and returns return chunk.write(messages());
Next:
Represent the message function with {#messages /} in your dust template
To clean up my code, I decided to put all of my schemas and routes into different files in my directory, and require them in my app.js. Each Schema corresponds to each route. For all but one of my routes, I have gotten this to work, but for one specific one, I cannot find out why I am getting it as undefined.
Here is the code I have in my app.js (the main file)
// Schemas
const Transaction = require ("./models/transaction");
User = require ("./models/user");
Ticket = require ("./models/ticket");
Job = require ("./models/job");
Client = require ("./models/client");
// Routes
require("./routes/users")(app);
require("./routes/tickets")(app);
require("./routes/clients")(app);
require("./routes/jobs")(app);
require("./routes/transactions")(app);
All of these work, except for my transaction route.
Here is its schema:
// =======================Transaction Schema "./models/transaction"
var transactionSchema = new mongoose.Schema({
job: String,
client: String,
deposited_by_user: String,
transaction_info:{
amount: mongoose.Decimal128,
method: String,
receipt_number: String,
date: {type: Date}
},
billing_address: {
street: String,
city: String,
state: String,
zip: String
},
notes: String,
date_added: {type: Date, default: Date.now}
});
module.exports = mongoose.model("Transaction", transactionSchema);
And its route:
module.exports = function(app) {
// =======================Transaction "./routes/transactions"
// index
app.get("/transactions", function(req, res){
Transaction.find({}, function(err, transactions){ // It is at this line where it is telling me that "Transaction" is undefined. However, with this code pasted into the app.js exactly the same as it is here, it works fine.
if(err){
console.log("error")
} else {
for (let i = 0; i < transactions.length; i++){
transactions[i]["transaction_info"]["new_amount"] = numberWithCommas(transactions[i]["transaction_info"]["amount"]);
}
res.render("transactions", {transactions: transactions});
}
});
});
// new
app.get("/transactions/add", async function(req, res){
let endCollections = [];
for (let i = 0; i < collections.length; i++){
await collections[i].find({}, function(err, foundCollection){
if (err) {
console.log(err);
} else {
endCollections[i] = foundCollection;
}
});
}
res.render("add_transaction", {users: endCollections[0], clients: endCollections[2], jobs: endCollections[3]});
});
// show
app.get("/transactions/:id", function(req, res){
Transaction.findById(req.params.id, function(err, foundTransaction){
if (err){
console.log(err);
} else {
// Redirect
let price = numberWithCommas(foundTransaction["transaction_info"]["amount"]);
res.render("transaction", {transaction: foundTransaction, price: price});
}
});
});
// edit
app.get("/transactions/:id/edit", function(req, res){
Transaction.findById(req.params.id, async function(err, foundTransaction){
if (err){
console.log("error")
} else {
let endCollections = [];
for (let i = 0; i < collections.length; i++){
await collections[i].find({}, function(err, foundCollection){
if (err) {
console.log(err);
} else {
endCollections[i] = foundCollection;
}
});
}
let deposit_date = foundTransaction["transaction_info"]["date"];
deposit_date = moment(deposit_date).format("MM-DD-YYYY");
res.render("edit_transaction", {transaction: foundTransaction, users: endCollections[0], clients: endCollections[2], jobs: endCollections[3], deposit_date: deposit_date});
}
});
});
// create
app.post("/transactions", function(req, res){
// Create Transaction
Transaction.create(req.body.transaction, function(err, newTransaction){
if (err){
console.log(err)
} else {
// Redirect
res.redirect("/transactions");
}
});
});
// update
app.put("/transactions/:id", function(req, res){
// Update transaction
Transaction.findByIdAndUpdate(req.params.id, req.body.transaction, function(err, updatedTransaction){
if (err){
console.log(err)
} else {
// Redirect
res.redirect("/transactions/" + req.params.id);
}
});
});
// delete
app.delete("/transactions/:id", function(req, res){
// Delete job
Job.findByIdAndRemove(req.params.id, function(err, deletedTransaction){
if (err){
console.log(err)
} else {
// Redirect
res.redirect("/transactions");
}
});
});
}
I do not believe the Schema is the problem because when I paste the Transaction route code directly into my app.js file, character for character, it works fine. However, with it split (and the code stays exactly the same in the transactions.js file) I am getting the error when I load the page that "Transaction is undefined" at the part of my code that starts with Transaction.find
Overall, I cannot understand why when the route is in the app.js file, it works just fine, but when it is in a separate file, the Transaction variable is considered undefined; this is all despite it being modeled exactely the same as my other routes and schemas. Is there something here I am not seeing? Thanks.
1)
Instead of:
app.get("/transactions", function(req, res){
.
.
app.get("/transactions/:id", function(req, res){
Maybe just:
app.get("/", function(req, res){
.
.
app.get("/:id", function(req, res){
and so on?
2)
Transaction.find({}, function(err, transactions){
Instead of {} try ()
Transaction.find((), function(err, transactions){
It looks as you are passing one empty object
I have a simple app that requires a REST API call to perform CRUD (Create,Read,Update,Delete). However, i can't seem to get the REST API working.
When it's executing the put operation, i'm getting
"api.js:81 Uncaught (in promise) SyntaxError: Unexpected end of JSON input
at callAPI (api.js:81)"
I'm using Api.js to check the API calls.
api-photos.js
//photos.js
var express = require('express');
var router = express.Router();
var multer = require('multer');
var photoController = require('../../controllers/photoController');
var upload = multer({
storage: photoController.storage,
fileFilter: photoController.imageFilter
});
//import PhotoService
const PhotoService = photoController.PhotoService;
router.use((req, res, next)=>{
//set mime type for all request and origin
res.set({
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,OPTIONS',
"Access-Control-Allow-Headers":"Content-Type, Access-Control-Allow-Headers",
'Content-type':'applicaion/json'
});
if(req.method == 'OPTIONS'){
return res.status(200).end();
}
next();
})
// photos - list
router.get('/', (req, res, next)=>{
PhotoService.list()
//returns promise - argument passed photos
.then((photos)=>{
console.log(`API: Found images: ${photos}`);
res.status(200);
//set content type header to application/json - set correct mime type
res.send(JSON.stringify(photos));
});
})
// photos/:photoid - find
router.get('/:photoid', (req, res, next)=>{
PhotoService.read(req.params.photoid)
//returns promise - argument passed photos
.then((photo)=>{
console.log(`API: Found images: ${photo}`);
res.status(200);
//set content type header to application/json - set correct mime type
res.send(JSON.stringify(photo));
}).catch((err)=>{
});
});
// /photos POST create
router.post('/', upload.single('image'), async (req, res, next)=>{
var path = "/static/img/" + req.file.filename;
var photo = {
originalname: req.file.originalname,
mimetype: req.file.mimetype,
imageurl: path,
title: req.body.title,
filename: req.file.filename,
description: req.body.description,
size: req.file.size / 1024 | 0
}
//calling on photo service to return json object
try{
const photoSave = await PhotoService.create(photo);
res.status(201);
res.send(JSON.stringify(photoSave));
}catch(err){
console.log(err);
throw new Error("PhotoSaveError", photo);
}
});
// /photos/photoid: PUT - update
router.put('/:photoid', (req, res, next)=>{
console.log(`putting ${req.params.photoid}`);
let putdata = req.body;
PhotoService.update(req.params.photoid, putdata)
console.log()
.then((updatePhoto)=>{
res.status(200);
res.send(JSON.stringify(updatedPhoto));
}).catch((err)=> {
res.status(404);
res.end();
});
});
// /photos/photoid: DELETE - delete
router.delete('/:photoid', (req, res, next)=>{
PhotoService.delete(req.params.photoid)
.then((photo) => {
console.log(`Found images: $(photo)`);
res.status(200);
res.send(JSON.stringify(photo));
}).catch((err)=> {
res.status(404);
res.end();
});;
});
module.exports = router;
photo.js
//photos.js
var express = require('express');
var router = express.Router();
var app = express();
var multer = require('multer');
var photoController = require('../controllers/photoController');
var flash = require('express-flash');
//create upload object- intialize
var upload = multer({
storage: photoController.storage,
fileFilter: photoController.imageFilter
});
//Photo model import is required
var Photo = require('../models/photoModel');
const PhotoService = photoController.PhotoService
//flash messaging
router.use(flash());
//LIST - Get request to search database for our photos
router.get('/', (req, res, next)=>{
//search the DB for the photos
PhotoService.list()
.then((photos)=>{
//call photos view
res.render('photos', {
photos : photos,
flashMsg: req.flash("fileUploadError")
});
})
.catch((err)=>{
if (err) {
res.end("ERROR!");
}
});
});
//FIND - route for getting photo Details with form for editing
router.get('/:photoid', (req, res, next)=>{
console.log("finding "+req.params.photoid);
PhotoService.read({'_id': req.params.photoid})
//return promoise then handle it to render photo
.then((photo)=>{
res.render('updatePhoto', {
photo: photo,
flashMsg: req.flash("photoFindError")
});
}).catch((err)=>{
if (err) console.log(err);
});
});
//DELETE - route for deleting the photos
router.delete('/delete/:photoid', function(req, res){
PhotoService.delete({'_id': req.params.photoid})
.then((photos) => {
res.redirect('/photos');
});
});
//UPDATE - route for posting newly updated details
router.post('/:photoid', (req, res, next)=>{
PhotoService.update({'_id': req.params.photoid})
//return promoise then set photo data details
.then((photo)=>{
var data = {
title: req.body.title,
description: req.body.description
}
//set the data, save the photo details and redirect to photo list
photo.set(data);
photo.save().then(()=>{
res.redirect('/photos');
});
})
.catch((err)=>{
if (err) console.log(err);
});
});
//CREATE - post fields to the server and save them
router.post('/', upload.single('image'), (req, res, next)=>{
var path = "/static/img/" + req.file.filename;
var photo = {
originalname: req.file.originalname,
mimetype: req.file.mimetype,
imageurl: path,
title: req.body.title,
filename: req.file.filename,
description: req.body.description,
size: req.file.size / 1024 | 0
}
//Saving photo to DB
var photo = new Photo(photo);
photo.save()
.then(()=>{
//redirect after save, if succesfull
res.redirect('/photos');
})
//Catch error logs error
.catch((err)=>{
if (err){
console.log(err);
throw new Error("PhotoSaveError", photo);
}
});
});
//function will get called if above gets unhandled error - flash to display image and redirect
router.use(function(err, req, res, next){
console.error(err.stack);
if (err.message == "OnlyImageFilesAllowed"){
req.flash('fileUploadError', "Please select an image file with jpg, png, or gif")
res.redirect('/photos');
//2nd condition error if there was a problem saving
} else if (err.message == "PhotoSaveError"){
req.flash('photoSaveError', "There was a problem saving the photo")
res.redirect('/photos');
} else{
next(err);
}
});
//export the module
module.exports = router;
api.js
// wrap in IIFE to control scope
(function(){
const baseURL = 'http://localhost:8080';
function testAPIs(){
// test list first
var testId = '';
var testJSON = {};
// list
callAPI('GET', '/api/photos', null, null)
.then((list)=>{
console.log('\n\n***************************\nlist results:');
console.log(list);
testId = list[0]._id;
// create
let input = document.querySelector('input[type="file"]')
let data = new FormData()
data.append('image', input.files[0]);
data.append('title', 'My API Test Title');
data.append('description','This is an AJAX API test');
callAPI('POST', '/api/photos', null, data)
.then((photo)=>{
photoId = photo._id;
savedPhoto = photo; // keep a handle to the created photo object
console.log('\n\n***************************\ncreate results:');
console.log(photo);
// find
callAPI('GET','/api/photos/'+photoId, null, null)
.then((photo)=>{
console.log('\n\n***************************\nfind results:');
console.log(photo);
// update
testJSON.description += ' appended by the AJAX API ';
callAPI('PUT','/api/photos/'+photoId, null, savedPhoto)
.then((photo)=>{
console.log('\n\n***************************\nupdate results:');
console.log(photo);
//delete
callAPI('DELETE', '/api/photos/'+photoId, null, null)
.then((result)=>{
console.log('\n\n***************************\ndelete result:');
console.log(result);
})
});
});
});
})
.catch((err)=>{
console.error(err);
});
}
async function callAPI(method, uri, params, body){
jsonMimeType = {
'Content-type':'application/json'
}
try{
/* Set up our fetch.
* 'body' to be included only when method is POST
* If 'PUT', we need to be sure the mimetype is set to json
* (so bodyparser.json() will deal with it) and the body
* will need to be stringified.
* '...' syntax is the ES6 spread operator.
* It assigns new properties to an object, and in this case
* lets us use a conditional to create, or not create, a property
* on the object. (an empty 'body' property will cause an error
* on a GET request!)
*/
var response = await fetch(baseURL + uri, {
method: method, // GET, POST, PUT, DELETE, etc.
...(method=='POST' ? {body: body} : {}),
...(method=='PUT' ? {headers: jsonMimeType, body:JSON.stringify(body)} : {})
});
return response.json(); // parses response to JSON
}catch(err){
console.error(err);
return "{'status':'error'}";
}
}
// Calls our test function when we click the button
// afer validating that there's a file selected.
document.querySelector('#testme').addEventListener("click", ()=>{
let input = document.querySelector('input[type="file"]')
if (input.value){
testAPIs();
}else{
alert("please select an image file first");
}
});
})();
Here is an update PUT handler which should stop throwing "undefined .then of ...", note that updatePhoto needed to be renamed to updatedPhoto as well.
router.put('/:photoid', (req, res, next) => {
console.log(`putting ${req.params.photoid}`);
let putdata = req.body;
PhotoService.update(req.params.photoid, putdata).then((updatedPhoto) => {
res.status(200);
res.send(JSON.stringify(updatedPhoto));
}).catch((err) => {
res.status(404);
res.end();
});
});
And if you are using node 8+ you can use async/await. It simplifies the code and makes the problems easier to see:
router.put('/:photoid', async (req, res, next) => {
try {
console.log(`putting ${req.params.photoid}`);
let putdata = req.body;
const updatedPhoto = await PhotoService.update(req.params.photoid, putdata);
res.status(200);
res.send(JSON.stringify(updatedPhoto));
} catch (e) {
res.status(404);
res.end();
}
});
I have been building out a tagging system for my ExpressJS application and I have been able to create my routing to pick up on the individual tags that are used for my record, but the issue I am running into is trying to display content associated with the selected tag. For instance a record has a tag "Mouse", when clicked the route correctly goes to /tag/mouse, but I'm not sure if I should use a loop within my template to display only those values or if I should really be using a method within my route. I'm currently using nothing and the value being displayed on the tag page is undefined. I have a feeling the route method is what I am looking for.
Here is the main focus of my routes file:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var blogDB = require('../config/blogDB.js');
var Blogpost = require('./models/blogModel.js');
var paginate = require('express-paginate');
var http = require('http');
var path = require('path');
var aws = require('aws-sdk');
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 getSearchCriteria(params) {
return {
blogUrl: params.blogpost_blogUrl
};
}
router.route('/blog/:blogpost_blogUrl')
.get(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
Blogpost.findOne(searchCriteria, function (err, blogpost) {
if (err)
res.send(err);
res.render('pages/blogpost', {
blogpost: blogpost
})
})
})
.put(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
var updated = getBlogpostUpdate(req.body)
Blogpost.findOneAndUpdate(searchCriteria, updated, function (err, updated) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
})
.delete(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
Blogpost.findOneAndRemove(searchCriteria, function (err, removed) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
router.get('/tag/:blogpost_tags', function(req, res, next) {
Blogpost.paginate({}, req.query.page, req.query.limit, function(err, pageCount, blogpost, itemCount) {
if (err) return next(err)
if (err)
res.send(err);
res.format({
html: function() {
res.render('pages/tag', {
blogpost: blogpost,
pageCount: pageCount,
itemCount: itemCount
})
},
json: function() {
res.json({
object: 'blogpost',
has_more: paginate.hasNextPages(req)(pageCount),
data: blogpost
})
}
}); // END res.format(html, json)
}, {sortBy: {'date': -1} } ); // END Blogpost.paginate
});
Model:
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate');
var Schema = mongoose.Schema;
var BlogPostSchema = new Schema({
title: String,
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);
Tag page (EJS):
<html>
<head>
<% include ../partials/head %>
</head>
<body>
<header>
<% include ../partials/header %>
</header>
<div class="container">
<div class="col-md-12">
<%= blogpost.tags %>
</div>
</div>
<footer>
<% include ../partials/footer %>
</footer>
</body>
</html>
I am trying to be able to update my content via my editor, but I'm wondering what part of my application I should be modifying to be able to do this. I have a feeling that it is through the route file, but was wondering if there was a hyperlink method that I should be using from within my view to be able to generate my view with the content I want to edit.
Here is my route file:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var blogDB = require('../config/blogDB.js');
var Blogpost = require('./models/blogModel.js');
var paginate = require('express-paginate');
var http = require('http');
var path = require('path');
var aws = require('aws-sdk');
var AWS_ACCESS_KEY = process.env.AWS_ACCESS_KEY;
var AWS_SECRET_KEY = process.env.AWS_SECRET_KEY;
var S3_BUCKET = process.env.S3_BUCKET;
//index
router.use(paginate.middleware(10, 50));
router.route('/')
// 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)
if (err)
res.send(err);
res.format({
html: function() {
res.render('pages/index', {
blogpost: blogpost,
pageCount: pageCount,
itemCount: itemCount
})
},
json: function() {
res.json({
object: 'blogpost',
has_more: paginate.hasNextPages(req)(pageCount),
data: blogpost
})
}
}); // END res.format(html, json)
}, {sortBy: {'date': -1} } ); // END Blogpost.paginate
}); // END GET method
router.get('/sign_s3', function(req, res){
aws.config.update({accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY });
var s3 = new aws.S3();
var s3_params = {
Bucket: S3_BUCKET,
Key: req.query.s3_object_name,
Expires: 60,
ContentType: req.query.s3_object_type,
ACL: 'public-read'
};
s3.getSignedUrl('putObject', s3_params, function(err, data){
if(err){
console.log(err);
}
else{
var return_data = {
signed_request: data,
url: 'https://'+S3_BUCKET+'.s3.amazonaws.com/'+req.query.s3_object_name
};
res.write(JSON.stringify(return_data));
res.end();
}
});
});
router.route('/admin/posts/create')
// START POST method
.post(function(req, res) {
console.log("New instance");
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; // 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) {
res.render('pages/blogpost-create');
});
function getSearchCriteria(params) {
return {
blogUrl: params.blogpost_blogUrl
};
}
router.route('/blog/:blogpost_blogUrl')
.get(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
Blogpost.findOne(searchCriteria, function (err, blogpost) {
if (err)
res.send(err);
res.render('pages/blogpost', {
blogpost: blogpost
})
})
})
.put(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
var updated = getBlogpostUpdate(req.body)
Blogpost.findOneAndUpdate(searchCriteria, updated, function (err, updated) {
if (err)
res.send(err);
res.json({ message: 'Blog updated.' });
});
})
.delete(function (req, res) {
var searchCriteria = getSearchCriteria(req.params);
Blogpost.findOneAndRemove(searchCriteria, function (err, removed) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
//about
router.get('/about', function(req, res) {
res.render('pages/about');
});
//resume
router.get('/resume', function(req, res) {
res.render('pages/resume');
});
//portfolio
router.get('/portfolio', function(req, res) {
res.render('pages/portfolio');
});
//login
router.route('/login')
.get(function(req, res) {
res.render('pages/login.ejs', {
message: req.flash('loginMessage')
});
})
.post(passport.authenticate('local-login', {
successRedirect : '/admin',
failureRedirect : '/login',
failurFlash : true
}));
//sign up
/*
router.route('/signup')
.get(function(req, res) {
res.render('pages/signup.ejs', {
message: req.flash('signupMEssage')
});
})
.post(passport.authenticate('local-signup', {
successRedirect : '/admin',
failureRedirect : '/signup',
failurFlash : true
}));
*/
//admin dashboard
router.get('/admin', isLoggedIn, function(req, res, next) {
Blogpost.paginate({}, req.query.page, req.query.limit, function(err, pageCount, blogpost, itemCount) {
if (err) return next(err)
if (err)
res.send(err);
res.format({
html: function() {
res.render('pages/admin', {
user: req.user,
blogpost: blogpost,
pageCount: pageCount,
itemCount: itemCount
})
},
json: function() {
res.json({
object: 'blogpost',
has_more: paginate.hasNextPages(req)(pageCount),
data: blogpost
})
}
}); // END res.format(html, json)
}, {sortBy: {'date': -1} } ); // END Blogpost.paginate
});
//logout
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
//middleware to make sure user is logged in
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
module.exports = router;
Blogpost.ejs (Where I'm trying to create a link to edit the post):
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
</head>
<body>
<div class="container">
<div class="page-header">
<h1>Admin</h1>
<h2>Welcome user <%= user.local.email %></h2>
Logout
</div>
<div class="row">
<!-- LOCAL INFORMATION -->
<div class="col-sm-6">
<h3>New Post</h3>
<div class="well">
<h3><span class="fa fa-user"></span> Local</h3>
<p>
<strong>id</strong>: <%= user._id %><br>
<strong>email</strong>: <%= user.local.email %><br>
</p>
</div>
<h3><u>Published Blogposts</u></h3>
<% blogpost.forEach(function(blogpost) { %>
<h4><%= blogpost.title %> Edit</h4>
<% }); %>
</div>
</div>
</div>
</body>
</html>