Save Changes to a Note


#41

Is there a way to use Storage.vault.remove() to delete the old attachments? And… how would I find the key for the attachment? file.filename?


#42

It should be similar to the way we get an object here https://github.com/AnomalyInnovations/serverless-stack-demo-client/blob/master/src/containers/Notes.js#L31.

attachmentURL = await Storage.vault.get(attachment);

#43

I was getting the following error when trying to upload a new file:

ETagMissing: No access to ETag property on response. Check CORS configuration to expose ETag header.

I believe My CORS config was correct, see below. I added the Etag to my cors config and that fixed the issue but shouldn’t this be covered by the AllowedHeader line?

<ExposeHeader>ETag</ExposeHeader>

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

#44

That is weird. I haven’t seen this error before. What did your final CORS config end up looking like?


#45

My ‘saving’ and ‘deleting’ of notes is stuck in loading mode and never actually is accomplished. I logged on to Cloud Watch to try and see what was going on and my execution log looked ok from what I could tell but I am getting the following alarm:


#46

Yeah this basically means that Dynamo is trying to auto-scale because it is going over capacity. You can check in the CloudWatch logs if your requests are timing out.


#48

I’m getting the “KeyTooLongError” when I try to delete the previous attachment. The 400 error that is returned shows two extra characters “25” towards the end of the key for some reason.

My awsLin.js

export async function s3Delete(fileKey) {
    console.log("fileKey: " +fileKey);
    const removed = await Storage.vault.remove(fileKey);
    console.log(removed);
    return removed;
}

My Notes.js

  handleSubmit = async event => {
    event.preventDefault();
    let attachment;
    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 {
      if (this.file) {
        if (this.state.attachmentURL) {
          await s3Delete(this.state.attachmentURL);
        }
        attachment = await s3Upload(this.file);
      }
      await this.saveNote({
        content: this.state.content,
        attachment: attachment || this.state.note.attachment
      });
      this.props.history.push("/");
    } catch (e) {
      alert(e);
      this.setState({ isLoading: false });
    }
  }


#49

What is the fileKey in your case? Is it the full URL of the S3 file?


#50

It is the response from Storage.vault.get() and does appear to be an URL for the S3 file.

  async componentDidMount() {
    try {
      let attachmentURL;
      const note = await this.getNote();
      const { content, attachment } = note;

      if (attachment) {
        attachmentURL = await Storage.vault.get(attachment);
      }

      this.setState({
        note,
        content,
        attachmentURL,
      });
    } catch (e) {
      alert(e);
    }
  }

  getNote() {
    return API.get("notes", `/notes/${this.props.match.params.id}`);
  }

#51

I don’t remember exactly but I don’t think the key is supposed to be the full URL it might just be the file name?


#52

For anyone trying to find out what the ‘filekey’ is for deleting a file.
The Storage’s remove() function takes in a key to remove the file.
The key is the file name.
In your Notes.js, this will be: this.state.note.attachment

We set this in the s3Upload function in our awsLib.js file. We took the file in as a parameter, and we formatted a filename to pass into the Storage.vault.put() method as {CurrentTimesStamp}-{file.name}

const filename =${Date.now()}-${file.name} <- this is what we used to create the file. Would make sense we also use this to remove the file.

If you want to be sure, you can console.log(note) in your componentDidMount() right after fetching the note with this.getNote(), and look at what is listed in the ‘attachment’ field


#53

Thanks for the added details!