Uploading an image to Amazon S3 - help (really) needed

Hi

I’m really hoping someone on freeCodeCamp can help me.

For a bit of a background - I’ve been coding for just under a year now. I’ve been learning primarily JavaScript based languages (Node.js, React etc), and would describe myself as an intermediate now. Definitely not a beginner, but not an expert (unsurprisingly considering how short a time it’s been) either. I can code ‘full-stack’ websites with a back-end and an OK front-end.

I’m now getting to the stage where I get basic concepts, but learning more advanced stuff is hard. Take for example a project I’m working on right now - an estate agents website. I want to upload images to ‘blob’ storage, Amazon S3, but store text-based values in a Mongo database.

I’ve built the front-end, I’ve built most of the back-end. My Mongo database is working great for now. However, I just can’t work out how to upload to Amazon S3.

I’ve grown increasingly frustrated with Stack Overflow over the last few months - people have either been really blunt and saying I should ‘just read the documentation’, some have sent links to websites with tutorials that don’t help, or I don’t get any response at all.

Anyway - to the code. So, I’ve built a POST route, which has a subsequent function. I’ll try and go through step by step explaining the thought behind it.

As a quick note, this is basically exactly the same as the AWS S3 Node.Js documentation

app.post("/homes/store", function(req, res) {

  AWS.config.update({
    accessKeyId: process.env.ID,
    secretAccessKey: process.env.SECRET,
    region: 'eu-west-1'
  });

This first section is just initialising AWS from the SDK. Not a problem so far.

  s3 = new AWS.S3({});

  let uploadParams = {
    Bucket: 'test-bucket',
    Key: 'test-image',
    Body: 'test upload'
};

The second part is initialising S3 and creating a variable for uploadParams which will later be called in S3.upload.

let file = '';

This part has confused me the most - AWS state the contents of ‘file’ is a ‘process.arg[3]’. I don’t know what should be contained in here?

  let fileStream = fs.createReadStream(file);
fileStream.on('error', function(err) {
  console.log('File Error', err);
});

uploadParams.Body = fileStream;
uploadParams.Key = path.basename(file);

s3.upload (uploadParams, function (err, data) {
  if (err) {
    console.log("Error", err);
  } if (data) {
    console.log("Upload Success", data.Location);
  }
});
});

The rest is all basically copied and pasted from the documentation.

What I’m aiming to do is POST a form from my front-end, and save the attached file in to my S3 database. I’m not sure how to access this file (I assumed body-parser and ‘req.body.file’?) but I get an error then stating that path’s argument needs to be a string.

I’d really appreciate if anyone would be kind enough to help me re-factor this. I’m guessing I need to use Multer in here somewhere, but tutorials online really haven’t helped me understand.

I know there’s a freeCodeCamp one, but I’m struggling with it as it doesn’t have code examples in there and I’m not a good enough coder to understand what arguments to pass in without seeing it visually.

Thank you - let me know if anything is unclear or if you need anymore info. :smile:

let file = '';

Since you use file in the createReadStream function, my guess is that file should be the path to whatever file you want to upload (as per this source).

uploadParams.Body = fileStream;
Whatever uploadParams.Body does here, see if you can get the value that is supposed to be stored in fileStream by other means (just as a potential solution).

Did you try converting this value into a string first?

Let me know if any of that helped.

P.S. I agree with you about Stack Overflow. You ask a completely new question and they still flag it as a duplicate :laughing:. I tend to use it just to read the solutions that other people have gotten, not to ask questions.

On the contrary, being able to read documentation is a skill you really should learn as a programmer, as it is very powerful and will increase your ability to explore less popular tools with less community support. Sometimes you just need to do a bit of debugging to see how a function or api works (because some documentation is really bad :smile:)! That’s just my 2 cents. I’m intermediate also.

1 Like

Thanks for the response! Really appreciate it. :slight_smile:

I actually managed to figure this out by myself yesterday by (you guessed it) reading the documentation. I introduced Multer and Multer S3 middleware and it’s working great.

I am now just stuck on a different issue in that I need to somehow link the pictures being uploaded to S3 to my MongoDB database - but again, can’t get my head round it.

Thanks again.

You’re welcome. Glad to see that you solved your problem.