title: Images Save Even When Form Submit Fails In Nodejs Project Using Multer and HTML
body: <p>I am working on a Nodejs project and currently attempting to figure out how to prevent images uploaded through a form from being saved when the form submit fails (i.e. due to empty fields).
  I have looked other several other posts, Google, and multer documentation but have not been able to figure out how to stop the upload from occurring. Here is the code to my repo: <a href="https://github.com/halsheik/RecipeWarehouse.git" rel="nofollow noreferrer">https://github.com/halsheik/RecipeWarehouse.git</a>. Below, I have posted any relevant code. Thanks for any help.</p>
  <pre><code>// Modules required to run the application
  const express = require('express');
  const multer = require('multer');
  const crypto = require('crypto');
  const path = require('path');
  const { ensureAuthenticated } = require('../config/auth');
  
  // Creates 'mini app'
  const router = express.Router();
  
  // Models
  const Recipe = require('../models/Recipe'); // Recipe Model
  
  // Set up storage engine
  const storage = multer.diskStorage({
      destination: function(req, file, callback){
          callback(null, 'public/uploads');
      },
  
      filename: function(req, file, callback){
          crypto.pseudoRandomBytes(16, function(err, raw) {
              if (err) return callback(err);
            
              callback(null, raw.toString('hex') + path.extname(file.originalname));
          });
      }
  });
  
  const upload = multer({
      storage: storage
  });
  
  // My Recipes
  router.get('/myRecipes', ensureAuthenticated, function(req, res){
      Recipe.find({}, function(err, recipes){
          if(err){
            console.log(err);
          } else {
            res.render('./home/myRecipes', {
              recipes: recipes
            });
          }
        });
  });
  
  // My Recipes
  router.get('/createRecipe', ensureAuthenticated, function(req, res){
      res.render('./home/createRecipe');
  });
  
  // Create Recipe
  router.post('/createRecipe', ensureAuthenticated, upload.single('recipeImage'), function(req, res){
      const { recipeName, recipeDescription, ingredients, directions } = req.body;
      let errors = [];
  
      // Checks that all fields are not empty
      if(!recipeName || !recipeDescription || !ingredients || !directions){
          errors.push({ msg: 'Please fill in all fields.' });
      }
  
      // Checks that an image is uploaded
      if(!req.file){
          errors.push({ msg: 'Please add an image of your recipe' });
      }
  
      // Checks for any errors and prevents recipe creation if any
      if(errors.length &gt; 0){
          // Displays create Recipe form along with errors
          res.render('./home/createRecipe', {
              errors
          });
      } else {
          // Create a new 'Recipe' using our model
          const newRecipe = new Recipe({
              recipeName: recipeName,
              author: req.user._id,
              recipeImageFileName: req.file.filename,
              recipeDescription: recipeDescription,
              ingredients: ingredients,
              directions: directions,
          }); 
  
          // Saves recipe to mongoDB database
          newRecipe.save().then(function(){
              res.redirect('/recipes/myRecipes');
          }).catch(function(err){
              console.log(err);
          });
      }
  });
  
  // Get Single Recipe
  router.get('/:id', function(req, res){
      // Searches for a 'Recipe' with a unique 'id'
      Recipe.findById(req.params.id, function(err, recipe){
          if(err){
              throw err;
          }
  
          // Renders the Recipe in its own page with full information
          res.render('./home/recipe.ejs', {
              recipe: recipe
          });
      });
    });
  
  // Delete recipe
  router.delete('/:id', function(req, res){
      const query = {_id: req.params.id}
    
      Recipe.deleteOne(query, function(err){
          if(err){
            console.log(err);
            throw err;
          }
          
          res.send('Success');
      });
    });
  
  module.exports = router;
  </code></pre>
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang=&quot;en&quot;&gt;
      &lt;head&gt;
          &lt;!-- Required meta tags --&gt;
          &lt;meta charset=&quot;UTF-8&quot;&gt;
          &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
          &lt;title&gt;Homemade&lt;/title&gt;
  
          &lt;!-- Required program scripts --&gt;
          &lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue/dist/vue.js&quot;&gt;&lt;/script&gt;
          &lt;script src=&quot;https://code.jquery.com/jquery-3.5.1.js&quot; integrity=&quot;sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
          
          &lt;!-- Style Sheets--&gt;
          &lt;link rel=&quot;stylesheet&quot; href=&quot;/styles/navBarStyle.css&quot;&gt;
          &lt;link rel=&quot;stylesheet&quot; href=&quot;/styles/myRecipesStyle.css&quot;&gt;
          &lt;link rel=&quot;stylesheet&quot; href=&quot;/styles/createRecipeStyle.css&quot;&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;!-- Background image --&gt;
          &lt;img id=&quot;background&quot; src=&quot;/images/foodBackground.jpg&quot; alt=&quot;&quot;&gt;
  
          &lt;div id=&quot;newRecipeContainer&quot;&gt;
              &lt;div id=&quot;closeButtonContainer&quot;&gt;
                  &lt;div id=&quot;backButton&quot;&gt;&lt;a id=&quot;back&quot; href=&quot;/recipes/myRecipes&quot;&gt;&amp;larr; My Recipes&lt;/a&gt;&lt;/div&gt;
              &lt;/div&gt;
              
              &lt;form id=&quot;createRecipeForm&quot; action=&quot;/recipes/createRecipe&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
                  &lt;label id=&quot;formSubHeading&quot;&gt;Create Your Homemade Recipe&lt;/label&gt;
  
                  &lt;div id=&quot;recipeNameContainer&quot;&gt;
                      &lt;label id=&quot;recipeNameLabel&quot;&gt;Title&lt;/label&gt;
                      &lt;input id=&quot;recipeNameInput&quot; type=&quot;text&quot; name=&quot;recipeName&quot;&gt;
                  &lt;/div&gt;
  
                  &lt;div id=&quot;recipeImage&quot;&gt;
                      &lt;label id=&quot;recipeImageLabel&quot;&gt;Add An Image of Your Meal&lt;/label&gt;
                      &lt;input id=&quot;recipeImageInput&quot; type=&quot;file&quot; accept=&quot;image/*&quot; name=&quot;recipeImage&quot;/&gt; 
                      &lt;label id=&quot;recipeImageInputLabel&quot; for=&quot;recipeImageInput&quot; name=&quot;recipeImage&quot;&gt;Choose A File&lt;/label&gt;
                  &lt;/div&gt;
  
                  &lt;div id=&quot;recipeDescription&quot;&gt;
                      &lt;label id=&quot;recipeDescriptionLabel&quot;&gt;Description&lt;/label&gt;
                      &lt;textarea id=&quot;recipeDescriptionInput&quot; name=&quot;recipeDescription&quot; cols=&quot;30&quot; rows=&quot;10&quot; maxlength=&quot;2000&quot;&gt;&lt;/textarea&gt;
                  &lt;/div&gt;
  
                  &lt;div class=&quot;ingredientsContainer&quot;&gt;
                      &lt;label id=&quot;ingredientsLabel&quot;&gt;Ingredients&lt;/label&gt;
                      &lt;button id=&quot;addIngredientButton&quot; type=&quot;button&quot; @click=&quot;addIngredientForm&quot;&gt;Add Another Ingredient&lt;/button&gt;
              
                      &lt;div class=&quot;allIngredients&quot; v-for=&quot;(ingredient, ingredientIndex) in ingredients&quot;&gt;
                          &lt;label class=&quot;ingredientLabel&quot;&gt;{{ ingredientIndex + 1 }}.)&lt;/label&gt;
                          &lt;input class=&quot;ingredientInput&quot; type=&quot;text&quot; name=&quot;ingredients&quot; v-model=&quot;ingredient.ingredient&quot;&gt;
                          
                          &lt;button class=&quot;deleteIngredientButton&quot; type=&quot;button&quot; v-if=&quot;ingredientIndex &gt; 0&quot; @click=&quot;deleteIngredientForm(ingredientIndex)&quot;&gt;X&lt;/button&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
  
                  &lt;div class=&quot;directionsContainer&quot;&gt;
                      &lt;label id=&quot;directionsLabel&quot;&gt;Directions&lt;/label&gt;
                      &lt;button id=&quot;addDirectionButton&quot; type=&quot;button&quot; @click=&quot;addDirectionForm&quot;&gt;Add Another Direction&lt;/button&gt;
              
                      &lt;div class=&quot;allDirections&quot; v-for=&quot;(direction, directionIndex) in directions&quot;&gt;
                          &lt;label class=&quot;directionLabel&quot;&gt;{{ directionIndex + 1 }}.)&lt;/label&gt;
                          &lt;input class=&quot;directionInput&quot;type=&quot;text&quot; name=&quot;directions&quot; v-model=&quot;direction.direction&quot;&gt;
                          
                          &lt;button class=&quot;deleteDirectionButton&quot; type=&quot;button&quot; v-if=&quot;directionIndex &gt; 0&quot; @click=&quot;deleteDirectionForm(directionIndex)&quot;&gt;X&lt;/button&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  
                  &lt;div id=&quot;createRecipeButtonContainer&quot;&gt;
                      &lt;button id=&quot;createRecipeButton&quot; type=&quot;submit&quot;&gt;Create Recipe&lt;/button&gt;
                  &lt;/div&gt;
                  
              &lt;/form&gt;
          &lt;/div&gt;
  
          &lt;script src=&quot;/controls/newRecipeControl.js&quot;&gt;&lt;/script&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>Thanks again for any help.</p>