im trying to upload images on my app that's been served on heroku and it's says
ENOENT: no such file or directory
this is my code
router.post('/' ,multer({
storage : multer.diskStorage({
destination : (req , file , callback) => {
callback (null,'img')
} ,
filename : (req , file , callback) => {
callback(null , Date.now() + '-' + file.originalname)
}
})
})
and the architecture of my files
controllers
img this is the folder i want to upload to
public
routes
views
app.js
anyone can help >>>>?
https://help.heroku.com/K1PPS2WM/why-are-my-file-uploads-missing-deleted
Why are my file uploads missing/deleted?
The Heroku filesystem is ephemeral - that means that any changes to the filesystem whilst the dyno is running only last until that dyno is shut down or restarted. Each dyno boots with a clean copy of the filesystem from the most recent deploy. This is similar to how many container based systems, such as Docker, operate.
As a solution to this, I'd recommend you use an image serving service like imgur.com or cloudinary.com.
Related
I was building a twitter clone app where users can upload tweets with and without images. Before deploying my backend, everything worked fine. Users could upload tweets with and without images. However, after I deployed my backend, I've been unable to get users to upload a tweet with an image. I keep getting this error.
Error Enoent: no such file or directory
This happened after I deployed my backend to Render. It was working fine just before I deployed my backend It is currently impossible to upload an image at the moment. I think this has something to do with the way I'm setting the path in my multer middleware. Here's the middleware I use to upload images:
import multer from "multer";
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads");
},
filename: function (req, file, cb) {
cb(null, new Date().toISOString() + file.originalname);
},
});
const uploadFile = multer({ storage }).single("image");
export default uploadFile;
As you can see, I'm setting the storage path to "uploads". However, since I've deployed my backend somewhere else, I think it should be updated. Can anyone tell me how I should update it if I already have a backend hosted somewhere else. If I'm wrong and it has nothing to do with how I'm setting the path, can you tell me what's wrong and how to fix it? Thanks a lot!
So in my project I have folder /Pictures and everything else is all over the project folder. My problem is that I can access all the CSS , JS, HTML, but it doesn't let me get this image folder as a source of the web app.
I tried this(doesn't work):
app.get('/water.jpeg', function (req, res) {
res.sendFile(__dirname + '/' + "Pictures" + '/' + "water.jpeg");
});
I want all my images from the /Pictures folder to be a source for my web app.
if image uploads to '/uploads' folder then try like
app.use('/uploads', express.static(process.cwd() + '/uploads'))
__dirname gives you the directory name of entry point file. I don't know where is your entry point file in your application, but that's where you have to start.
By the way, I advise you to use the "join" function of the "path" module to concatenate the path so as it works on linux or window filesystem.
I found a solution by Quora here, thanks to everyone who helped :) :
link
I'm using the Mern stack, but I'm having an issue as to where to save uploaded files. Let me explain.
I have a form that sends over a formdata which includes a .jpg image.
On Node/express side, I receive it well. But now I'm stuck.
I'm using express-fileupload package which attaches an mv function that allows me to store my file in a directory.
In my endpoint, I have this snippet:
const img1= req.files.image1;
const img1Name = img1.name;
img1.mv("NOT-SURE-WHERE-TO-MAKE-MY-DIRECTORY"+img1Name, (err) => {
if (err) {
return res.status(500).json({message: 'Could Not mv file'});
} else {
return res.status(200).json({message: 'mv done'});
}
})
Where do I create the directory to store the .jpg image?
Do I create it in the client's src? or client's public?
Or, do I run the npm-run-build command to create my build folder and then point my mv function to save the file in there?
create a static file middleware in node app.js file to public directory then # public/images
If not try using multer it is much easier to upload Files
The goal: Have a Node.js server which will take a pdf from a PUT call, and return each page converted to a .jpg. Ultimately, I don't care how it gets done, of course.
I've successfully created a Node.js server which uses imagemagick to convert a pdf to an image. It's an express server, and it uses this imagemagick npm package, which wraps the imagemagick CLI.
Here's the code for the route, which works very well running locally
app.put('/v1/convert-pdf', (req, res) => {
res.status(202).send({ message: "we're working on it, alright?!" })
console.log("beginning image conversion")
im.convert(["-density", "144", "./content/pdf/foo.pdf", "./content/img/bar.jpg"], (err, stdout) => {
if (err) {
console.error(err)
} else {
console.log(stdout)
console.log("finished converting pdfs");
}
})
})
The route above outputs a bunch of .jpg files named foo-0.jpg, foo-1.jpg, etc... Now what I want to do is take a file, which is put to the route, convert it via imagemagick and then give it back to the user (eventually I'll put it in an S3 bucket, but baby steps).
If it does require saving the file to a folder in Heroku, how do I do that? I've attempted to read/write from Heroku, and I don't get an error (unless one of the files/directories doesn't exist), but I don't see the file either.
Summarising our conversation in comments here in case it's helpful to anyone:
The reason you won't be able to see the files that were created and saved by the application when you run heroku run bash is because that actually spins up a new dyno and doesn't have access to the file system of the dyno running the app.
As mentioned, the best way to do this is to upload the resultant images to something like S3 as soon as the conversion is complete, and to serve any incoming requests to retrieve those files through S3.
If running a single web dyno this wouldn't be a problem right now, but if you're running multiple then the converted files will only be available on the dyno that received and transformed the PDF, so other dynos won't have access to them.
Also, each deployment creates new dynos, so unless you store those files in something like S3, they'll be lost as soon as you push up.
I'm working through designing my first webapp, I've already written a significant portion of the frontend and now I want to make a very simple backend to begin implementing some of the functionality. I've spent the last few days learning as much as I can about effective backend development and other various things, but I've run into a huge problem. I fundamentally don't understand how to attach my front end and my backend (which I want to use nodejs for).
All I want is to use my browser to go to localhost:8080 and automatically see the html document with my frontend then within my frontend code have the app communicate with the server (to get json info or instruct the server to add things to a database or things like that).
Once you have installed node in your system.
Folder structure:
Keep your files in public folder inside app folder
Navigate to your application folder in Terminal or Command Prompt:
Then create a file as package.json and keep following code in it:
{
"name" : "YourAppName",
"version" : "0.0.1",
"description" : "App description",
"dependencies" : {
"mime" : "~1.2.7"
}
}
then come back to terminal and run npm install
Then create a file as server.js and keep following code in it:
var http = require("http");
var fs = require("fs");
var path = require("path");
var mime = require("mime");
var cache = {};
function send404(responce){
responce.writeHead(404,{"content-type":"text/plain"});
responce.write("Error 404: resourse not found");
responce.end()
}
function sendFile(responce,filePath,fileContents){
responce.writeHead(200,{"content-type": mime.lookup(path.basename(filePath))});
responce.end(fileContents);
}
function serveStatic(responce,cache,abspath){
if(cache[abspath]){
sendFile(responce,abspath,cache[abspath]);
}else{
fs.exists(abspath,function(exists){
if(exists){
fs.readFile(abspath,function(err,data){
if(err){
send404(responce);
}else{
cache[abspath] = data;
sendFile(responce,abspath,data);
}
})
}else{
send404(responce)
}
})
}
}
var server = http.createServer(function(request,responce){
var filePath = false;
if(request.url == '/'){
filePath = 'public/index.html';
}else{
filePath = 'public'+request.url;
}
var abspath = './'+filePath;
serveStatic(responce,cache,abspath);
})
server.listen(8080,function(){
console.log("server running on 3000");
})
** This code is to help you get started with node js, for better understanding go to node documentation. Read about the mime module too, it is being used here.
You can use free cloud services such as Parse.com. this js sdk
You can use Grunt and using Connect plugin, create a simple server, sufficient for developing pure JS web applications.
Using Grunt basically requires 2 files
package.json
Gruntfile.js
package.json defines the dependencies required by Grunt to run. In your case it would include
grunt
grunt-contrib-connect (The plugin for setting up a server)`
It may also include additional dependencies based on your requirements.
Gruntfile.js defines the configuration for dependencies. In your case how the server should be setup. If you use plugins other that grunt-contrib-connect you should configure them too.
Reference:
Grunt: The JavaScript Task Runner