Comments for Delete a Note

From @jayair on Fri Apr 20 2018 17:30:31 GMT+0000 (UTC)

@alex-romanov A couple of things to check. Check the CORS config we set in this chapter - https://serverless-stack.com/chapters/create-an-s3-bucket-for-file-uploads.html. And make sure the IAM policy in the chapter is set properly - https://serverless-stack.com/chapters/create-a-cognito-identity-pool.html. There are also some tips on debugging the IAM policy here - https://serverless-stack.com/chapters/debugging-serverless-api-issues.html#missing-iam-policy.

Added a delete function to aws-libs. It works but how can I get information out of the promise I get from delete a file? I want to know if the delete was succesfull e.g. if the file existed. The docs says: * Promise resolves upon successful removal of the object but I don’t know what that means.

 export async function s3Delete(filename) {
     const promise = await Storage.vault.remove(filename);
 
     //how do I check if object was successfully removed?
 
     return true;
 }

I’m not entirely sure for this case but for promises with async/await you want to use the try/catch pattern. So wrap it in a try/catch and it should throw an error if it failed to remove it.

1 Like

Hey @namelesswc can you help me? I think Storage.remove() needs the key of the file right? How did you get it? I can only get the URL

EDIT: the request doesn’t throw an error, I tried to construct the key myself, it worked, but S3 responds with a 204 and doesn’t delete the file!

I think you just need the key of the file. This is the same as the one we used while uploading the file. If you have the URL strip the rest of the URL info to just get the filename.

@jayair Yeah got it just now reading again! Since the key on the AWS console includes stuff like “private/…” I thought we needed that here as well. Thanks

1 Like

Love the tutorial so far. Only I can’t get the delete function to work. The function works when i try

serverless invoke local --function delete --path mocks/delete-event.json

But within the react app I get:

Access to XMLHttpRequest at 'https://a5pggk0dqb.execute-api.eu-central-1.amazonaws.com/prod/notes/7f2eeca0-9288-11e9-ba32-e783dbce76e9' 
from origin 'http://localhost:3000' has been blocked by CORS policy: 
Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.

POST, PUT works fine…

I also tried to update the response-lib.js to:

function buildReponse(statusCode, body) {
    return {
        statusCode: statusCode,
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Credentials": true,
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET,PUT,DELETE"
        },
        body: JSON.stringify(body)
    };
}

with no effect

Can you check the CORS flag in your serverless.yml for this function?

  delete:
    handler: delete.main
    events:
      - http:
          path: notes/{id}
          method: delete
          cors: true
          authorizer: aws_iam

Not sure what is happening. When I call delete using the aws-amplifiy API.del() method, I get a response of 200, but the row is not getting deleted in the dynamoDb table. I have already checked the serverless.yml, Cloudwatch doesn’t seem to have anything, the delete.js api is correct, I am really confused on this one. My CORS configuration is fine too I double checked that.

Nevermind, I forgot an await keyword in the delete.js file. Not really sure why this makes the diffference tho, is it because the function is returning before the async call to the database fires off?

I’m having trouble getting the delete note API endpoint to work. Whenever I try to access it, I end up with a “The Provided Key does not match schema error”, and this is because the userid is null, and I believe this is probably because for some reason the request-context is not getting populated. I don’t know why this is the case, as this is only happening with my delete function, and not my other functions, and I haven’t noticed any differences between them.

Was the await keyword on the call to DynamoDB? If so, then that makes sense. You want to make sure that call completes before returning.

One way to work with these issues is to compare your code to the one in the repo. Let me know if that helps.

I figured out the problem. It was in my serverless.yml, I had not properly indent

 - http:
          path: notes/{id}
          method: put
          cors: true
          authorizer: aws_iam

On any on the functions after my get function. I did not notice because all the other functions were still working despite this.

Hi All, Just wanted to share my experience in implementing the delete and update features. Of course there are gurus here, who know far more and will be able to provide better guidance.

Based on anomalyinnovations’s inputs, I re-jigged the methods slightly. Within the awsLib.js, I created this function:

export async function deleteS3Object(file) {
    const access = { level: "private" };

    const removed = await Storage.vault.remove(file,access);

    return removed.key;
}

Then within Notes.js, I changed the handleSubmit method to the following. This allows removing the existing file attachment and reattaching the new file.

async function handleSubmit(event) {
    let attachment;

    event.preventDefault();

    if (file.current && file.current.size > config.MAX_ATTACHMENT_SIZE) {
        alert(
            `Please pick a file smaller than ${config.MAX_ATTACHMENT_SIZE /
            1000000} MB.`
        );
        return;
    }

    setIsLoading(true);

    try {
        if (file.current) {
            /* Before saving the new attachment, get rid of the old attachment */
            await deleteS3Object(note.attachment);
            attachment = await s3Upload(file.current);
        }

        await saveNote({
            content,
            attachment: attachment || note.attachment
        });

        props.history.push("/");
    } catch (e) {
        alert(e);
        setIsLoading(false);
    }
}

Then to delete the attachment after deleting the Note, I changed the handleDelete method to the following:

async function handleDelete(event) {
    event.preventDefault();

    const confirmed = window.confirm(
        "Are you sure you want to delete this note?"
    );

    if (!confirmed) {
        return;
    }

    setIsDeleting(true);

    try {
        await deleteNote();
        /* This is where we delete the attachment */
        await deleteS3Object(note.attachment);
        props.history.push("/");
    } catch (e) {
        alert(e);
        setIsDeleting(false);
    }
}

Hope this helps.

Please review and let me know if this can be done any better.

Best regards

1 Like

Hi,

When pressing the delete button I receive the following ‘Error: Request failed with status code 500’.
I am able to update and save the note with no issues.

Any help would be greatly appreciated.

Thanks

Thanks for sharing all the details!

You’ll need to check out the logs to see what’s going on here. Add a console.log to your delete.js Lambda function for this.

I have a question regarding the delete note. Initially, I ran into a bug setting up the cognito pool. I noticed that the copy/paste policy referenced an endpoint as

"arn:aws:execute-api:YOUR_API_GATEWAY_REGION:*:YOUR_API_GATEWAY_ID/*/*/*"

Notably, the “///" did not work for me and I noticed the screenshot only included "/”, so I changed it to this and then the API test worked. HOWEVER, now that the app is setup and the API call for delete necessitates the extra slashes/stars because it is referenced as “/notes/{id}/delete” I am getting “Error could not load resource my delete endpoint” and a 500 response. I presume this is because my permissions do not give access beyond a single “/*” in the endpoint URL.

I am not sure how to fix this - “///" seems to be overkill and does not work for the requests that do not include the extra id parameter, however, switching to a single "/” prevents delete from working. Is there a way I can give permission to both?

Hmmm I’m having a hard time following the slashes. Can you show me some examples of what you did?