dtetreau251 / serverless

GNU General Public License v3.0
0 stars 1 forks source link

Bunnimage frontend #19

Closed dtetreau251 closed 3 years ago

ghost commented 3 years ago

Week 4 Step 2 ⬤⬤◯◯◯◯◯ | 🕐 Estimated completion: 20-25 minutes

Error Handling ~ Sir this is a Wendy's

Demo: 🐰

Ideally, users will fill the web form with the correct information. However, people make mistakes. In this step, we will be implementing some form validation to make sure that a user has inputted text value before submitting their password.

✅ Task:

🚧 Test your Work

Open up your LiveServer plugin and start your server.

:pencil: You have three test cases to try
1. **The "correct" way**: Submit both a file and text. Check that you receive "Thanks!" 2. **The "unexpected" way (file)**: Submit a file that is not png or jpeg. Does it work? 3. **The "unexpected" way (text input)**: Try submitting without entering a username. You should get an alert box that says "No name error."

Preventing the Page from Reloading

By default, the website will reload whenever a user presses submit. This leads to our text on the page that we set being cleared away. We can prevent this by adding this to the top of our getImage() function:

event.preventDefault()

Accepting Images as an Input

In HTML Forms, the enctype attribute specifies how the form-data should be encoded when submitting it to the server. Like we learned before, if we want to upload files, we need send form-data encoded as multipart/form-data

    <h1>Bunnimage</h1>
    <form onsubmit="getImage(event)" enctype="multipart/form-data">
        <label>Code: </label>

To add the image upload input, add an additional file input within the form & change the submit button's type.

<form onsubmit="getImage(event)" enctype="multipart/form-data">
   <input type="file" name="image"></input>
   <input id="name" type="text"  placeholder="Enter your file's name">
   <input type="submit" />

Input Validation?

We need to validate two things.

:one: The image is either in the .png or .jpeg format
The HTML `` accept Attribute specifies a filter for what file types the user can pick from the file input dialog box. The accept attribute can only be used with . ```html
```

:two: The text box isn't empty
To validate that the name isn't null, check if `document.getElementById("username").value` isn't empty, to change the `output` div to "Thanks!", or display an `alert("No name error.")` > :bulb: **Hint**: Use your JavaScript conditional skills!

ghost commented 3 years ago

Week 4 Step 3 ⬤⬤⬤◯◯◯◯ | 🕐 Estimated completion: 20-25 minutes

Making fetch Happen

Demo: 🐰

We are going to how use the form to call our Azure Function! Yay :tada:! Things are coming together.

✅ Task:

🚧 Test your Work

Open up your LiveServer plugin and start your local server. To test your web app:

:one: Upload an image and click submit. Do you get a "Your image has been stored successfully!" message?

:two: Log into your Azure portal and navigate to your storage account. In your container, do you see your image?

How do I get form data?

To get the information the user entered in the form, you will need to create a FormData object. FormData lets you compile a set of key/value pairs to send.

var bunniForm = document.getElementById("YOUR_FORM_ID");
var payload = new FormData(bunniForm);
const file = fileInput.files[0]; // fileInput is the file upload input element
payload.append("file", file);
:question: What's happening here?
Code breakdown: - we reference the html form element with `document.getElementById("YOUR_FORM_ID")`, so we can create a FormData object. - we extract the file the user uploaded using `fileInput.files[0]` - finally, we add the file created to the `FormData` object using `append`, and a key-value pair. The key is `file`, and its value is the file itself. 💡 Since we need to reference the form element in `document.getElementById("YOUR_FORM_ID")`, we need to give it an id in the html. ```html ``` > Now, we can send the payload to our azure function in the body of our fetch request.

How do I call the Azure Function?

The Fetch API is built in to Javascript to make HTTP requests (using GET, POST and other methods), download, and upload files.

:bulb: We don't have to install node-fetch as an npm package since fetch is built into JavaScript. Remember: we were using NodeJS before.

To start a request, call the special function fetch():

const response = await fetch(resource, options);

Fetch accepts two arguments:

:question: What does fetch exactly do?
`fetch()` starts a request and returns a promise. When the request completes, the promise is resolved with the Response object. **If the request fails due to some network problems, the promise is rejected.** > Keep this in mind if your function throws a promise error!

How to configure "options"

In order to pass the type of method, the payload in the pody, and headers, you have to configure the "options" part of the fetch function.

const response = await fetch(resource, {
   method: ... ,
   body: ... , 
   headers: { ... }
});

Fill in the method, headers and body with the correct information compatible with your API!

:bulb: Refer back to previous Fetch requests we made in NodeJS for hints. Remember for this request, we are not receiving JSON!

How to validate that the upload worked

We need to let the users know if the upload was successful! We do this by making sure we receive a response from our upload API:

❗ Use a "try...catch"
A [`try...catch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch) is what it sounds like - it catches errors. This makes for a better user experience and is crucial to error handling. ```js try { // Try receiving data from your fetch request // Change the output div's value } catch (e) { // If an error occurred, tell the user! } ```

Update CORS Settings

CORS (Cross-origin resource sharing) settings tells the Function App what domains (such as wwww.website.com) can make requests to the Azure Functions.

:exclamation: How can I change it?
Head to your function app in your portal and find the button on the left hand side called `CORS`. ![https://user-images.githubusercontent.com/69332964/99188905-6f0b7c00-272c-11eb-8142-f91882227c78.png](https://user-images.githubusercontent.com/69332964/99188905-6f0b7c00-272c-11eb-8142-f91882227c78.png)

:question: What should I change it to?
Change it to a wildcard operator (`*`), which allows *all* origin domains to make requests. > :bulb: Be sure to remove any other existing inputs before attempting to save with wildcard. **Don't forget to save your changes!**

ghost commented 3 years ago

Week 4 Step 4 ⬤⬤⬤⬤◯◯◯ | 🕐 Estimated completion: 5-20 minutes

Downloading your image!

Demo: 🐰

Write and connect a JS file to make a GET request to the download Azure function that includes the codename to receive the link. Edit the button on the HTML page so that it downloads the file when clicked.

✅ Task:

🚧 Test your Work

Open up your LiveServer plugin and start your local server. To test your web app:

⚠️ Type in the username for an image you have uploaded previously. Does the download button link to your file?

Opening a link

window.open() is fairly straightforward to use. Here's the syntax:

window.open(URL, name, specs, replace)

We will only be using URL and name. Use this documentation to fill it in.

ghost commented 3 years ago

⏰ Time to merge!

Go ahead and merge this branch to main to move on. Great work finishing this section!

merge

⚠️ If you receive a Conflicts error, simply press Resolve conflicts and you should be good to merge!