Microsoft | Development for beginners (Episode 17)

This lesson covers the basics of GitHub, a platform to host and manage changes to your code.

 · 8 phút đọc.

This lesson covers the basics of GitHub, a platform to host and manage changes to your code.

Introduction

In this lesson, you’ll call an API by submitting your browser extension’s form and displaying the results in your browser extension. In addition, you’ll learn about how you can store data in your browser’s local storage for future reference and use.

Set up the elements to manipulate in the extension:

By this time you have built the HTML for the form and results <div> for your browser extension. From now on, you’ll need to work in the /src/index.js file and build your extension bit by bit. Refer to the previous lesson on getting your project set up and on the build process.

Working in your index.js file, start by creating some const variables to hold the values associated with various fields:

JavaScript
// form fields
const form = document.querySelector('.form-data');
const region = document.querySelector('.region-name');
const apiKey = document.querySelector('.api-key');

// results
const errors = document.querySelector('.errors');
const loading = document.querySelector('.loading');
const results = document.querySelector('.result-container');
const usage = document.querySelector('.carbon-usage');
const fossilfuel = document.querySelector('.fossil-fuel');
const myregion = document.querySelector('.my-region');
const clearBtn = document.querySelector('.clear-btn');

All of these fields are referenced by their css class, as you set it up in the HTML in the previous lesson.

Add listeners

Next, add event listeners to the form and the clear button that resets the form, so that if a user submits the form or clicks that reset button, something will happen, and add the call to initialize the app at the bottom of the file:

form.addEventListener('submit', (e) => handleSubmit(e));
clearBtn.addEventListener('click', (e) => reset(e));
init();

✅ Notice the shorthand used to listen for a submit or click event, and how the event it is passed to the handleSubmit or reset functions. Can you write the equivalent of this shorthand in a longer format? Which do you prefer?

Build out the init() function and the reset() function:

Now you are going to build the function that initializes the extension, which is called init():

function init() {
//if anything is in localStorage, pick it up
const storedApiKey = localStorage.getItem('apiKey');
const storedRegion = localStorage.getItem('regionName');

//set icon to be generic green
//todo

if (storedApiKey === null || storedRegion === null) {
//if we don't have the keys, show the form
form.style.display = 'block';
results.style.display = 'none';
loading.style.display = 'none';
clearBtn.style.display = 'none';
errors.textContent = '';
} else {
//if we have saved keys/regions in localStorage, show results when they load
displayCarbonUsage(storedApiKey, storedRegion);
results.style.display = 'none';
form.style.display = 'none';
clearBtn.style.display = 'block';
}
};

function reset(e) {
e.preventDefault();
//clear local storage for region only
localStorage.removeItem('regionName');
init();
}

In this function, there is some interesting logic. Reading through it, can you see what happens?

– Two const are set up to check if the user has stored an APIKey and region code in local storage.

– If either of those is null, show the form by changing its style to display as ‘block’

– Hide the results, loading, and clearBtn and set any error text to an empty string

– If there exists a key and region, start a routine to:: call the API to get carbon usage data, hide the results area, hide the form, show the reset button.

Before moving on, it’s useful to learn about a very important concept available in browsers: LocalStorage. LocalStorage is a useful way to store strings in the browser as a key-value pair. This type of web storage can be manipulated by JavaScript to manage data in the browser. LocalStorage does not expire, while SessionStorage, another kind of web storage, is cleared when the browser is closed. The various types of storage have pros and cons to their usage.

Note – your browser extension has its own local storage; the main browser window is a different instance and behaves separately.

You set your APIKey to have a string value, for example, and you can see that it is set on Edge by “inspecting” a web page (you can right-click a browser to inspect) and going to the Applications tab to see the storage.

✅ Think about situations where you would NOT want to store some data in LocalStorage. In general, placing API Keys in LocalStorage is a bad idea! Can you see why? In our case, since our app is purely for learning and will not be deployed to an app store, we will use this method.

Notice that you use the Web API to manipulate LocalStorage, either by using getItem(), setItem(), or removeItem(). It’s widely supported across browsers.

Before building the displayCarbonUsage() function that is called in init(), let’s build the functionality to handle the initial form submission.

Handle the form submission

Create a function called handleSubmit that accepts an event argument (e). Stop the event from propagating (in this case, we want to stop the browser from refreshing) and call a new function, setUpUser, passing in the arguments apiKey.value and region.value. In this way, you use the two values that are brought in via the initial form when the appropriate fields are populated.

function handleSubmit(e) {
e.preventDefault();
setUpUser(apiKey.value, region.value);
}

✅ Refresh your memory – the HTML you set up in the last lesson has two input fields whose values are captured via the const you set up at the top of the file, and they are both required so the browser stops users from inputting null values.

Set up the user

Moving on to the setUpUser function, here is where you set local storage values for apiKey and regionName. Add a new function:

function setUpUser(apiKey, regionName) {
localStorage.setItem('apiKey', apiKey);
localStorage.setItem('regionName', regionName);
loading.style.display = 'block';
errors.textContent = '';
clearBtn.style.display = 'block';
//make initial call
displayCarbonUsage(apiKey, regionName);
}

This function sets a loading message to show while the API is called. At this point, you have arrived at creating the most important function of this browser extension!

Display Carbon Usage

Finally, it’s time to query the API!

Before going further, we should discuss APIs. APIs, or Application Programming Interfaces, is a critical element of a web developer’s toolbox. They provide standard ways for programs to interact and interface with each other. For example, if you are building a web site that needs to query a database, someone might have created an API for you to use. While there are many types of APIs, one of the most popular is a REST API.

✅ The term ‘REST’ stands for ‘Representational State Transfer’ and features using variously-configured URLs to fetch data. Do a little research on the various types of APIs available to developers. What format appeals to you?

There are important things to note about this function. First, notice the async keyword. Writing your functions so that they run asynchronously means that they wait for an action, such as data being returned, to be completed before continuing.

Here’s a quick video about async:

Async and Await for managing promises

🎥 Click the image above for a video about async/await.

Create a new function to query the C02Signal API:

import axios from '…/node_modules/axios';

async function displayCarbonUsage(apiKey, region) {
try {
await axios
.get('https://api.co2signal.com/v1/latest', {
params: {
countryCode: region,
},
headers: {
'auth-token': apiKey,
},
})
.then((response) => {
let CO2 = Math.floor(response.data.data.carbonIntensity);

//calculateColor(CO2);

loading.style.display = 'none';
form.style.display = 'none';
myregion.textContent = region;
usage.textContent =
Math.round(response.data.data.carbonIntensity) + ' grams (grams C02 emitted per kilowatt hour)';
fossilfuel.textContent =
response.data.data.fossilFuelPercentage.toFixed(2) +
'% (percentage of fossil fuels used to generate electricity)';
results.style.display = 'block';
});
} catch (error) {
console.log(error);
loading.style.display = 'none';
results.style.display = 'none';
errors.textContent = 'Sorry, we have no data for the region you have requested.';
}
}

This is a big function. What’s going on here?

– following best practices, you use an async keyword to make this function behave asynchronously. The function contains a try/catch block as it will return a promise when the API returns data. Because you don’t have control over the speed that the API will respond (it may not respond at all!), you need to handle this uncertainty by calling it asynchronously.

– you’re querying the co2signal API to get your region’s data, using your API Key. To use that key, you have to use a type of authentication in your header parameters.

– once the API responds, you assign various elements of its response data to the parts of your screen you set up to show this data.

– if there’s an error, or if there is no result, you show an error message.

✅ Using asynchronous programming patterns is another very useful tool in your toolbox. Read about the various ways you can configure this type of code.

Congratulations! If you build your extension (npm run build) and refresh it in your extensions pane, you have a working extension! The only thing that isn’t working is the icon, and you’ll fix that in the next lesson.

🚀 Challenge

We’ve discussed several types of API so far in these lessons. Choose a web API and research in depth what it offers. For example, take a look at APIs available within browsers such as the HTML Drag and Drop API. What makes a great API in your opinion?

Review & Self Study

You learned about LocalStorage and APIs in this lesson, both very useful for the professional web developer. Can you think about how these two things work together? Think about how you would architect a web site that would store items to be used by an API.

Share:
Quay lại.

Có thể bạn chưa đọc

Xem tất cả »

Đăng ký nhận bảng tin hàng tuần

Liên lạc trao đổi

Liên lạc thông qua Instagram

Thông qua Instagram, bạn có thể trao đổi trực tiếp và tức thời, cũng như cập nhật những thông tin mới nhất từ nhavantuonglai.

Tức thời

Bạn có thể gửi và nhận tin nhắn nhanh chóng, trực tiếp, giúp những vấn đề cá nhân của bạn được giải quyết tức thời và hiệu quả hơn.

Thân thiện

Vì tính chất là kênh liên lạc nhanh, nên bạn có thể bỏ qua những nghi thức giao tiếp thông thường, chỉ cần lịch sự và tôn trọng thì sẽ nhận được sự phản hồi đầy thân thiện, thoải mái từ tác giả.

Trao đổi trên email

Thông qua email cá nhân, bạn có thể trao đổi thỏa thuận hợp tác, kết nối chuyên sâu và mang tính chuyên nghiệp.

Tin cậy

Trong một số trường hợp, email được dùng như một tài liệu pháp lý, chính vì vậy mà bạn có thể an tâm và tin cậy khi trao đổi với tác giả thông qua email.

Chuyên nghiệp

Cấu trúc của email đặt tính chuyên nghiệp lên hàng đầu, nên những thông tin, nội dung được viết trong email từ tác giả sẽ luôn đảm bảo điều này ở mức cao nhất.