I am trying to load images that are uploaded from a form to an index page. I have my public folder in app.js file mapped correctly and it is structured so that any image would be located at "/public/assets/img/filename.ext"
The schema I have for blog posts that are throwing errors is:
// schema setup
var mongoose = require("mongoose");
var postSchema = new mongoose.Schema({
title: String,
image: String,
uploadedImage: {
data: Buffer,
contentType: String,
},
dest: String,
postdata: String,
excerpt: String,
tag: String,
icon: String,
color: String,
featured: String,
keywords: String,
description: String,
slug: String,
create: {type: Date, default: Date.now},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
},
});
module.exports = mongoose.model("Posts", postSchema);
This schema is filled by a form that I created that has the following route structure:
require("dotenv").config();
const express = require("express"),
router = express.Router(),
Posts = require("../models/blog"),
upload = require("../middleware/upload"),
path = require('path'),
fs = require('fs'),
middleware = require("../middleware"),
slugify = require('slugify');
// CREATE
router.post("/", middleware.isLoggedIn, middleware.isAdmin, upload.single('uploadedImage'), function(req,res){
var title = req.body.title;
var image = req.body.image;
var postdata = req.body.postdata;
var exceprt = req.body.excerpt;
var tag = req.body.tag;
var icon = req.body.icon;
var color = req.body.color;
var featured = req.body.featured;
var keywords = req.body.keywords;
var description = req.body.description;
var dest = req.file.filename;
var slug = slugify(title);
var uploadedImage = {
data: fs.readFileSync(path.join('./public/assets/img/' req.file.filename)),
contentType: 'image/png'
};
var author = {
id: req.user._id,
username: req.user.username
};
// link dB to post values
var newPost= {title:title, slug:slug, image:image, postdata:postdata, excerpt:exceprt, tag:tag, icon:icon, color:color, featured:featured, author:author, keywords:keywords, description:description, dest:dest, uploadedImage:uploadedImage};
Posts.create(newPost, function(err, newlyCreated) {
if (err){
console.log(err);
}else{
console.log("slug:" slug);
console.log(req.file.path);
res.redirect("/blog");
}
});
});
And to serve it in my EJS I am calling it like so inside of my loop:
<% Posts.forEach(function(post){ %>
<img src="/assets/img/<%= post.dest %>" />
<% }); %>
The result is the right path to my public folder, but I get a 404 error every time that says the file does not exist. I have checked and the files do exist so I am a little lost as to why I am getting that error. I have tested at local level and AWS C9 console, but when I push to a staging site on Heroku I get the error.
Any suggestions or code corrections would be helpful.
CodePudding user response:
Anyone who uses Heroku will have this problem until you upgrade to a paid dyno. See this Heroku Doc that shows that the free tier goes to sleep. Since their system is transient and when a dyno sleeps it clears all uploaded files, that was the cause of my images not showing up in the templates. I tested this, and confirmed with a sales rep that because they are trying to remove their free tier this setting is fixed and will result in loss of data. Hope this helps someone, cheers!