Upload a File to S3
Let’s now add an attachment to our note. The flow we are using here is very simple.
- The user selects a file to upload.
- The file is uploaded to S3 under the user’s folder and we get a key back.
- Create a note with the file key as the attachment.
We are going to use the Storage module that AWS Amplify has. If you recall, that back in the Create a Cognito identity pool chapter we allow a logged in user access to a folder inside our S3 Bucket. AWS Amplify stores directly to this folder if we want to privately store a file.
Also, just looking ahead a bit; we will be uploading files when a note is created and when a note is edited. So let’s create a simple convenience method to help with that.
Upload to S3
Create a src/libs/
directory for this.
$ mkdir src/libs/
Add the following to src/libs/awsLib.js
.
import { Storage } from "aws-amplify";
export async function s3Upload(file) {
const filename = `${Date.now()}-${file.name}`;
const stored = await Storage.vault.put(filename, file, {
contentType: file.type
});
return stored.key;
}
The above method does a couple of things.
-
It takes a file object as a parameter.
-
Generates a unique file name using the current timestamp (
Date.now()
). Of course, if your app is being used heavily this might not be the best way to create a unique filename. But this should be fine for now. -
Upload the file to the user’s folder in S3 using the
Storage.vault.put()
object. Alternatively, if we were uploading publicly you can use theStorage.put()
method. -
And return the stored object’s key.
Upload Before Creating a Note
Now that we have our upload methods ready, let’s call them from the create note method.
Replace the handleSubmit
method in src/containers/NewNote.js
with the following.
handleSubmit = async event => {
event.preventDefault();
if (this.file && this.file.size > config.MAX_ATTACHMENT_SIZE) {
alert(`Please pick a file smaller than ${config.MAX_ATTACHMENT_SIZE/1000000} MB.`);
return;
}
this.setState({ isLoading: true });
try {
const attachment = this.file
? await s3Upload(this.file)
: null;
await this.createNote({
attachment,
content: this.state.content
});
this.props.history.push("/");
} catch (e) {
alert(e);
this.setState({ isLoading: false });
}
}
And make sure to include s3Upload
by adding the following to the header of src/containers/NewNote.js
.
import { s3Upload } from "../libs/awsLib";
The change we’ve made in the handleSubmit
is that:
-
We upload the file using the
s3Upload
method. -
Use the returned key and add that to the note object when we create the note.
Now when we switch over to our browser and submit the form with an uploaded file we should see the note being created successfully. And the app being redirected to the homepage.
Next up we are going to allow users to see a list of the notes they’ve created.
If you liked this post, please subscribe to our newsletter, give us a star on GitHub, and follow us on Twitter.
For help and discussion
Comments on this chapterFor reference, here is the code so far
Frontend Source :upload-a-file-to-s3