Urgent help on multer profile pic upload

This is three days of trying to create upload profile picture,but I can’t seems to. Is either the says pug cannot render image on views or

Error: ENOTDIR: not a directory, open ‘/app/pictures/uploads/IMG-20210817-WA0002.jpg’
etc.please help my client need the work in two days thank you.

index.js

var express = require('express');
var router = express.Router();
var path = require("path");
//multer object creation
var multer  = require('multer')

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, path.join(__dirname + '/../pictures/uploads'));
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname)
  }
})
 
var upload = multer({ storage: storage })
 module.exports = function(app){
//GET home page. 
app.route("/").get(function(req, res, next) {
  res.render( path.join(__dirname + "/../views/index.pug"));
});
 
app.route("/profile").post(upload.single('avatar'),function(req, res) {
  console.log(req.file);
  res.send("File upload sucessfully.");
});
 }

index.pug

html
   head
    title nanas personal portfolio
    meta(name='description', content='Profile')
    meta(charset='utf-8')
    meta(http-equiv='X-UA-Compatible', content='IE=edge')
    meta(name='viewport', content='width=device-width, initial-scale=1')
    link(rel='stylesheet', href='/public/style.css')
    header 
    div.profile-picture
      label choose/upload profile pic
      br
      form(action="/profile", accept="image/x-png,image/gif,image/jpeg",  method="post", enctype="multipart/form-data")
        input(type="file", id="file", name="avatar")
        br
        input(type="submit", value="upload")
        ```
PLEASE YOU CAN EDIT THE WORK IF POSSIBLE. OR SUGGESTIONS WITH CODE EXAMPLE CAN BE FINE

Hey, where do you get this error message? It looks like that piece of code is expecting a directory but you are passing it a file

1 Like

please explain more, actually from the root folder i added something like picture/uploads, while picture is the folder and uploads was a folder inside of picture folder. I dont know, but there was nothing picture/uploads.js. I sent the link can you assist may be editing thanks.

Sure, you said:

I am asking: when you see this error text, “Error: ENOTDIR: not a directory”, do your logs tell you which line of code is causing this error?

The cause of that error is that somewhere your code is trying to access the file IMG-20210817-WA0002.jpg as if it was a directory. I guess the file is a profile picture.

Your profile pic upload code looks ok to me. Maybe there is a problem in the code that tries to read and render the profile pic? And that is why you are getting the error above.

So, post more detail about the error if you can :slight_smile:

Sorry, I can’t help out individually, I just answer public questions for the benefit of all :slight_smile:

SteGriff your are right after all, the server needed directory while I was serving file. But this is it, I discover that nodejs express does not hold static files like images on it. The same way i serve the directory is the same way i got it when i use file system (fs). SteGriff, you see I have 3 days to submit this project to my client and am left with deployment after coupling file. If you don’t mind i look up to you for help when to complete the project. I will invite you to the main and the test site of the project to over see the work, BECAUSE am new to WEB Dev.
This is where am stuck after uploading the file.
I render the picture to pug views it stuck right inside img(src") with out displaying, even when i reduce the sise.

index.js

var express = require('express');
var app = express()
var path = require("path");
//multer object creation
var multer  = require('multer')
var fs = require("fs");
app.use(express.static(__dirname));

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
       fs.mkdir('./uploads/',(err)=>{
       cb(null, './uploads/');
    });
        //cb(null, path.join(__dirname +  '../public/uploads'));
    },
    filename: function (req, file, cb) {
    cb(null, Date.now() + file.originalname); }
})
 
var upload = multer({ storage: storage })
 module.exports = function(app){
//GET home page. 
app.route("/").get(function(req, res, next) {
  res.render( path.join(__dirname + "/../views/index.pug"));
});
 
app.route("/profile").post(upload.single('avatar'),function(req, res) {
  var image = req.file;
  console.log(image);
res.render(path.join(__dirname + "/../views/index.pug"), {image: image})
});
 }

index.pug

html
   head
    title nanas personal portfolio
    script.
      document.addEventListener("DOMContentLoaded", funtion(event){
        document.querySelector("img")
          img.style.height = "50px";
          img.style.width = "50px";
          display = "block"
      })
    meta(name='description', content='Profile')
    meta(charset='utf-8')
    meta(http-equiv='X-UA-Compatible', content='IE=edge')
    meta(name='viewport', content='width=device-width, initial-scale=1')
    link(rel='stylesheet', href='/public/style.css')
    header     
    img(src='./uploads/' + image)
    div.profile-picture
      label choose/upload profile pic
      br
      form(action="/profile", accept="image/x-png,image/gif,image/jpeg,image/jpg",  method="post", enctype="multipart/form-data")
        input(type="file", id="file", name="avatar")
        br
        input(type="submit", value="upload")

projTestLink: Glitch

Please how can I visualise or see the image withing the sketch box display, thank you.

If I go to your test site and view source, here’s what I see for image source:

image

In your pug code, you say

 img(src='./uploads/' + image)

But where is it going to get image from? You never gave that variable to the pug view.

So, in your index route, you need to send the image variable as part of the model. Take a look at the example in the Express docs Using template engines with Express

It looks like this:

app.get('/', function (req, res) {
  res.render('index', { title: 'Hey', message: 'Hello there!' })
})

So you need image instead of title or message.

You also need to decide on the server, which image you are going to send to the client. I guess you want a login system or something and send the image corresponding to the logged-in account. That is obviously a more complicated thing to do.

I hope this helps a bit.

Taking on professional projects is definitely a way of learning fast… but maybe take a little more learning time before your next project, or negotiate a longer deadline if you think you’ll have to learn stuff!

All the best

1 Like

Thanks I appreciate, i will keep you posted.

1 Like

Good morning SteGriff, using the method of JSON.stringify() I was able to render the image to pug, using #{image}. Now the whole API is render instead of the visual picture, which i understand i need to pass it to img() to display visual. I pass the #{} to img() and nothing happen. seems the img does not accept #{}. please any idea how to manipulate #{} inside img perhaps it will display visual image thanks.
the link still remain the same in case you need to check

I’m not sure why you’re JSON stringifying it, but this will work:

In index.pug

    body
      P.flash-Message welcom #{msg}
      img(src=pic)
      label choose/upload profile pic
      br

In routes/index.js


var upload = multer({ storage: storage });
module.exports = function(app) {
  //GET home page.
  app.route("/").get(function(req, res, next) {
    res.render(path.join(__dirname + "/../views/index.pug"));
  });

  app.route("/profile").post(upload.single("avatar"), function(req, res) {
    var pic = req.file.filename;
    console.log(pic);
    res.render(path.join(__dirname + "/../views/index.pug"), {
      msg: "we back",
      pic: `/uploads/${pic}`
    });
  });
};

Fixed demo project: Glitch :・゚✧

2 Likes

Good evening SteGriff, I have the problem solved with your suggestion. Now am trying to deploy it to Heroku. May be you might have some suggestion, i have first of all exported it to github, next exports to heroku and deploy automatic.

hello, my project has been pushed to github like i told you, now am suppose to fork the message and deploy it directly to heroku using the deploy button in github, but unfortunately i could not see the button. Base on the youtube video i watch it is like that and easy. please do you have another easier way to do this.