Skip to content

Latest commit

 

History

History
216 lines (163 loc) · 10.7 KB

http.md

File metadata and controls

216 lines (163 loc) · 10.7 KB

1. Write code that executes asynchronously

const handleSubmit = (e) => {
  e.preventDefault();
  const postcode = e.target.children[1].value;

  validatePostcode(postcode).then((result) => {
    if (result) {
      getBasicInfo(postcode).then((data) => displayBasicInfo(data));
      getNearestBuses(postcode).then((data) => displayTransportInfo(data));
    }
  });
};

This handleSubmit function is triggered when the user submits a form. Then, the validatePostcode function is called with the
postcode value provided by the user. This function returns a Promise which resolves with a boolean value indicating
whether the postcode is valid or not.

The .then method is used to handle the resolved value of the Promise returned by validatePostcode. If the postcode is
valid (result is true), then two API calls (getBasicInfo and getNearestBuses) are made to retrieve data about the postcode.

Each of these API calls also returns a Promise, and the .then method is used again to handle the resolved value of each Promise.
If the Promise is resolved successfully, the data is passed to a corresponding display function (displayBasicInfo or displayTransportInfo).

Since these API calls are asynchronous and return Promises, the JavaScript code does not block the main thread and
can execute other tasks while waiting for the API responses.

2. Use callbacks to access values that aren’t available synchronously

getLongAndLat(postcode).then((result) => {
  const { longitude, latitude } = result;
});

In this code snippet, the getLongAndLat function is called with the postcode parameter. This function returns
a promise that will eventually resolve with an object containing the longitude and latitude values.

The .then method is used to define a callback function that will be executed when the promise is resolved.
The callback function takes the resolved result as its parameter, which is the object containing longitude and latitude.

By using the .then method and the callback function, we can access the longitude and latitude values asynchronously,
once they become available, instead of trying to access them synchronously before the promise has been resolved.

3. Use promises to access values that aren’t available synchronously

await Promise.all(
  allQueryStrings.map((qs) =>
    fetch(qs)
      .then((response) => {
        if (response.ok) {
          progressBar.value = Math.floor(
            (++fetchNumber / totalFetches) * 100
          );
          progressBar.textContent = `${progressBar.value}%`;
          p.textContent = `Fetching crime data (${progressBar.value}%)`;
          return response.json();
        }
      }).catch((error) => {
        console.error("OH NO! This happened when fetching crime data:\n" + error);
        userInfoContainer.style.display = 'none';
      })
  )
)

This code uses the Promise.all() method to make multiple API requests at once and waits for all of them to resolve
before proceeding to the next step in the code. This help us to access values that aren't available synchronously because the code doesn't
have to wait for each request to finish before moving on to the next one.

Instead, it can continue executing the code and handle the data returned from each request once it's available.

4. Use the fetch method to make HTTP requests and receive responses

export const getBasicInfo = (postcode) => {
  return fetch(`https://api.postcodes.io/postcodes/${postcode}`)
    .then((response) => {
      if (response.ok) {
        return response.json().then((data) => data.result);
      } else {
        throw new Error(response.status);
      }
    })
    .catch((error) => console.log(error));
};

The fetch method is used to make a request to the specified URL and returns a Promise that resolves to a Response object.
The .then method is then used to handle the response object, where it checks if the response is okay using the response.okproperty.
If it is okay, it returns the JSON data from the response using the response.json() method and resolves it to the data.result.

If the response is not okay, the throw statement is executed with the response status as the argument. Finally, the catch method is
used to handle any errors that may occur during the fetch operation.

5. Configure the options argument of the fetch method to make GET and POST requests

fetch('https://echo.oliverjam.workers.dev/json', {
  method: 'POST',
  headers: {
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Zakarie',
    cohort: 'fac27',
  }),
})
  .then((response) => {
    if (response.ok) {
      response.json().then((data) => console.log(data));
    } else {
      throw new Error(response.status);
    }
  })
  .catch((error) => console.log(error));

The code snippet is an example of configuring the options argument of the fetch method to make a POST request.
The second argument of the fetch function is an object that includes several properties that configure the request. In this case, the method
property is set to "POST", indicating that the request is a POST request, and the headers property is an object that
specifies the content-type of the request as "application/json".

Finally, the body property is set to a JSON string that includes the data that will be sent as the body of the request.

6. Use the map array method to create a new array containing new values

const sanitizedPostcode = postcode
  .split('')
  .filter((char) => char !== ' ')
  .map((char) => char.toLowerCase())
  .join('');

There is a part in our codebase that requires a specific type of postcode to return the required result. So, we used the map method to create
a new array of transformed values. The split method is called on the postcode string to break it into an array of characters,
then the filter method is called on this array to remove any spaces.

The map method is then called on this filtered array to convert each character to lowercase. Finally, the join method
is called to join the lowercase characters back into a string.

7. Use the filter array method to create a new array with certain values removed

See above point. #6

8. Access DOM nodes using a variety of selectors

const basicInfoOutput = document.querySelector('#output__info');

We are using the querySelector method to select the first element that matches the CSS selector #output__info, which
is an element with the id attribute of output__info. We attach that element the basic info of the specified postcode.

This method can be used to select elements based on their ID, class, tag name, or other attributes. Once the element is selected,
it can be manipulated or used in other ways, such as adding content or event listeners.

9. Add and remove DOM nodes to change the content on the page

const basicInfoDiv = document.createElement('div');
---
document.querySelector('.postcodes__container').innerHTML = '';

The first line of the code creates a new div element called basicInfoDiv.

The second line of the code selects an element on the page with a class of postcodes__container using the document.querySelector()
method, and sets its innerHTML property to an empty string. This effectively removes any child elements previously contained
within the postcodes__container element.

Together, these two lines of code allow for the creation of a new element and the removal of any existing elements within a specified
container element, effectively changing the content on the page.

10. Toggle the classes applied to DOM nodes to change their CSS properties

By toggling a class on an element, we can separate the presentation logic from the JavaScript logic. This makes our code more modular
and easier to maintain. We can define CSS rules for the class in a separate stylesheet or in the same file, and they will apply to the element
whenever the class is added to or removed from it.

Toggling classes provides a more flexible, modular, and maintainable way to change the appearance of elements on a web page.

11. Use consistent layout and spacing

Using consistent layout and spacing in your code makes it more readable and easier to understand for both yourself and others who may
be working on the project. When code is consistently formatted, it's easier to quickly scan and identify key parts of the code, making it faster
to debug and maintain.

Additionally, consistent spacing can make it easier to identify nested blocks of code, which can be especially helpful in languages
that rely heavily on brackets, such as Javascript.

12. Follow a spacing guideline to give our app a consistent feel

Following a spacing guideline is important because it ensures that all elements on the page are laid out in a visually pleasing
and organized manner. Consistent spacing helps to create a clear visual hierarchy and makes it easier for users to scan and understand the content.

Inconsistent spacing can make an app look disorganized and chaotic, which can be confusing and frustrating for users.

13. Debug client side JS in our web browser

Debugging client-side JavaScript in a web browser is an essential skill for web developers.

Modern web browsers come with a set of developer tools that include a JavaScript console. The console allows you to execute JavaScript
code and view the output or any errors that may occur. You can also set breakpoints in the JavaScript code using the debugger statement.
When the code reaches the breakpoint, it pauses execution, allowing you to inspect the values of variables and step through the code one line at a time.

14. Use console.log() to help us debug our code

When we encounter a problem with our code, we can use console.log() to output messages to the browser console to help us
understand what is happening in our code and identify potential issues. By examining the output generated by
console.log(), we can often see the values of variables, the order in which functions are being called, and other important
information that can help us track down and fix problems in our code.