skip to Main Content

I’m using AWS S3 and MongoDB in a full-stack react application.

When I add a new recept in front-end it works normally. But once in a while it changes the rndImageName which I create on back-end. Images uploads to S3 fine.

Is there better way to do this?

multer.js

const randomImageName = (bytes = 32) => crypto.randomBytes(bytes).toString('hex')
let rndImageName = randomImageName();

awsRouter.post('/recipeImages', upload.single('file'), async (req, res) => {

  const buffer = await sharp(req.file.buffer).resize({ height: 1920, width: 1080, fit: 'contain' }).toBuffer()

  const params = {
    Bucket: bucketName,
    Key: 'recipeImages/' + rndImageName, 
    Body: buffer,
    ContentType: req.file.mimetype
  }

  const command = new PutObjectCommand(params)

  await s3.send(command)

})


recipes.js 

const { rndImageName } = require('./multer')

recipesRouter.post('/', async (request, response, next) => {

  const body = request.body

  const decodedToken = jwt.verify(getTokenFrom(request), process.env.SECRET)

  if (!decodedToken.id) {
    return response.status(401).json({ error: 'token invalid' })
  }
  const user = await User.findById(decodedToken.id)


  const recipe = new Recipe({
    id: body.id,
    recipe_name: body.recipe_name,
    ingredients: body.ingredients,
    instructions: body.instructions,
    speed: body.speed,
    category: body.category,
    main_ingredient: body.main_ingredient,
    diet: body.diet,
    likes: body.likes || 0,
    comments: body.comments || [],
    created: new Date(),
    imageName: rndImageName,
    user: user._id
  })

  const savedRecipe = await recipe.save()
  user.recipes = user.recipes.concat(savedRecipe._id)
  await user.save()

})

I want to insert the rndImageName (which I set up for S3 file name) to mongoDB objects so I can create signedUrl for a specific recipe.

Now it seems to use the same randomImageName again. Also changing the previously added recipe’s imageName.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks JCC288 for your advice. I figured it out by generating awImageName in front-end and sharing awsImageName for both routers.

    const handleSubmit = (event) => { event.preventDefault()

    const awsImageName = randomImgNameGenerator()
    
    handleImageAdd({file, imageSrc, awsImageName })
    
    handleRecipeAdd({
      recipe_name: newReceptName,
      ingredients: ingredients,
      instructions: instructions,
      speed: recipespeed,
      category: category,
      main_ingredient: mainIngredient,
      diet: diets,
      imageName: awsImageName
    })
    

  2. I haven’t had time to check it on my code. But from my analysis it is only running random image name once and the function keeps running because of the server running only called the function once when it reads the file. I think you can refactor and create helper function for getting the randomImgName in different file like

    randomImgNameGenerator.js

    function randomImgNameGenerator(){
       const randomImageName = (bytes = 32) => crypto.randomBytes(bytes).toString('hex')
    
       return randomImageName
    }
    

    And call it inside callback in multer. Like this

    awsRouter.post('/recipeImages', upload.single('file'), async (req, res) => {
    
      const buffer = await sharp(req.file.buffer).resize({ height: 1920, width: 1080, fit: 'contain' }).toBuffer()
    
      const params = {
        Bucket: bucketName,
        Key: 'recipeImages/' + randomImgNameGenerator(), 
        Body: buffer,
        ContentType: req.file.mimetype
      }
    
      const command = new PutObjectCommand(params)
    
      await s3.send(command)
    
    })
    

    And see will it helps

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search