You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/hr/5-browser-extension/2-forms-browsers-local-storage/README.md

19 KiB

Projekt proširenja preglednika, dio 2: Pozivanje API-ja, korištenje lokalne pohrane

Kviz prije predavanja

Pre-kviz predavanja

Uvod

Sjećate li se proširenja za preglednik koje ste počeli izrađivati? Trenutno imate lijep obrazac, ali on je zapravo statičan. Danas ćemo ga oživjeti povezivanjem s pravim podacima i dodavanjem memorije.

Razmislite o računalima za kontrolu misije Apollo - nisu samo prikazivala fiksne informacije. Neprestano su komunicirala sa svemirskim letjelicama, ažurirala podatke o telemetriji i pamtila ključne parametre misije. Takvo dinamično ponašanje gradimo danas. Vaše proširenje će se povezati s internetom, dohvatiti stvarne podatke o okolišu i zapamtiti vaše postavke za sljedeći put.

Integracija API-ja može zvučati složeno, ali zapravo se radi o tome da naučite svoj kod kako komunicirati s drugim uslugama. Bez obzira dohvaćate li podatke o vremenu, feedove društvenih mreža ili informacije o ugljičnom otisku kao što ćemo danas, sve se svodi na uspostavljanje tih digitalnih veza. Također ćemo istražiti kako preglednici mogu pohraniti informacije - slično kao što su knjižnice koristile kartoteke za pamćenje gdje se knjige nalaze.

Na kraju ove lekcije imat ćete proširenje za preglednik koje dohvaća stvarne podatke, pohranjuje korisničke postavke i pruža glatko iskustvo. Krenimo!

Slijedite numerirane segmente u odgovarajućim datotekama kako biste znali gdje postaviti svoj kod.

Postavljanje elemenata za manipulaciju u proširenju

Prije nego što vaš JavaScript može manipulirati sučeljem, potrebno je referencirati specifične HTML elemente. Zamislite to kao teleskop koji treba biti usmjeren na određene zvijezde - prije nego što je Galileo mogao proučavati Jupiterove mjesece, morao je locirati i fokusirati se na Jupiter.

U vašoj datoteci index.js, kreirat ćemo const varijable koje hvataju reference na svaki važan element obrasca. To je slično tome kako znanstvenici označavaju svoju opremu - umjesto da svaki put pretražuju cijeli laboratorij, mogu izravno pristupiti onome što im treba.

// 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');

Što ovaj kod radi:

  • Hvata elemente obrasca koristeći document.querySelector() s CSS selektorima klase
  • Stvara reference na polja za unos naziva regije i API ključa
  • Uspostavlja veze s elementima za prikaz rezultata podataka o ugljičnoj potrošnji
  • Postavlja pristup elementima korisničkog sučelja poput indikatora učitavanja i poruka o pogreškama
  • Pohranjuje svaku referencu elementa u const varijablu za jednostavno ponovno korištenje u vašem kodu

Dodavanje slušatelja događaja

Sada ćemo omogućiti vašem proširenju da reagira na korisničke radnje. Slušatelji događaja su način na koji vaš kod prati interakcije korisnika. Zamislite ih kao operatere u ranim telefonskim centralama - slušali su dolazne pozive i povezivali prave krugove kad je netko želio uspostaviti vezu.

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

Razumijevanje ovih koncepata:

  • Dodaje slušatelja za slanje obrasca koji se aktivira kada korisnici pritisnu Enter ili kliknu na slanje
  • Povezuje slušatelja klikova na gumb za brisanje radi resetiranja obrasca
  • Prosljeđuje objekt događaja (e) funkcijama za dodatnu kontrolu
  • Poziva funkciju init() odmah kako bi postavila početno stanje vašeg proširenja

Obratite pažnju na skraćenu sintaksu streličaste funkcije koja se ovdje koristi. Ovaj moderni pristup JavaScriptu je čišći od tradicionalnih izraza funkcija, ali oba jednako dobro funkcioniraju!

Izrada funkcija za inicijalizaciju i resetiranje

Izradimo logiku inicijalizacije za vaše proširenje. Funkcija init() je poput navigacijskog sustava broda koji provjerava svoje instrumente - određuje trenutno stanje i prilagođava sučelje u skladu s tim. Provjerava je li netko već koristio vaše proširenje i učitava njihove prethodne postavke.

Funkcija reset() korisnicima pruža svježi početak - slično kao što znanstvenici resetiraju svoje instrumente između eksperimenata kako bi osigurali čiste podatke.

function init() {
	// Check if user has previously saved API credentials
	const storedApiKey = localStorage.getItem('apiKey');
	const storedRegion = localStorage.getItem('regionName');

	// Set extension icon to generic green (placeholder for future lesson)
	// TODO: Implement icon update in next lesson

	if (storedApiKey === null || storedRegion === null) {
		// First-time user: show the setup form
		form.style.display = 'block';
		results.style.display = 'none';
		loading.style.display = 'none';
		clearBtn.style.display = 'none';
		errors.textContent = '';
	} else {
		// Returning user: load their saved data automatically
		displayCarbonUsage(storedApiKey, storedRegion);
		results.style.display = 'none';
		form.style.display = 'none';
		clearBtn.style.display = 'block';
	}
}

function reset(e) {
	e.preventDefault();
	// Clear stored region to allow user to choose a new location
	localStorage.removeItem('regionName');
	// Restart the initialization process
	init();
}

Razlaganje onoga što se ovdje događa:

  • Dohvaća pohranjeni API ključ i regiju iz lokalne pohrane preglednika
  • Provjerava je li ovo prvi put da korisnik koristi proširenje (nema pohranjenih podataka) ili se radi o povratnom korisniku
  • Prikazuje obrazac za postavljanje za nove korisnike i skriva ostale elemente sučelja
  • Automatski učitava spremljene podatke za povratne korisnike i prikazuje opciju za resetiranje
  • Upravlja stanjem korisničkog sučelja na temelju dostupnih podataka

Ključni koncepti o lokalnoj pohrani:

  • Čuva podatke između sesija preglednika (za razliku od sesijske pohrane)
  • Pohranjuje podatke kao parove ključ-vrijednost koristeći getItem() i setItem()
  • Vraća null kada ne postoje podaci za određeni ključ
  • Pruža jednostavan način za pamćenje korisničkih preferencija i postavki

💡 Razumijevanje pohrane u pregledniku: LocalStorage je poput davanja vašem proširenju trajne memorije. Zamislite kako je drevna Aleksandrijska knjižnica pohranjivala svitke - informacije su ostale dostupne čak i kad su se učenjaci vraćali.

Ključne karakteristike:

  • Čuva podatke čak i nakon zatvaranja preglednika
  • Preživljava ponovno pokretanje računala i padove preglednika
  • Pruža značajan prostor za pohranu korisničkih preferencija
  • Omogućuje trenutni pristup bez kašnjenja mreže

Važna napomena: Vaše proširenje za preglednik ima vlastitu izoliranu lokalnu pohranu koja je odvojena od uobičajenih web stranica. To pruža sigurnost i sprječava sukobe s drugim web stranicama.

Svoje pohranjene podatke možete pregledati otvaranjem Alata za razvoj preglednika (F12), navigacijom na karticu Application i proširivanjem odjeljka Local Storage.

Local storage pane

⚠️ Sigurnosno razmatranje: U produkcijskim aplikacijama, pohrana API ključeva u LocalStorage predstavlja sigurnosne rizike jer JavaScript može pristupiti tim podacima. Za potrebe učenja, ovaj pristup je u redu, ali stvarne aplikacije trebaju koristiti sigurnu pohranu na strani servera za osjetljive podatke.

Obrada slanja obrasca

Sada ćemo obraditi što se događa kada netko pošalje vaš obrazac. Po defaultu, preglednici ponovno učitavaju stranicu kada se obrasci pošalju, ali mi ćemo presresti ovo ponašanje kako bismo stvorili glatko iskustvo.

Ovaj pristup odražava način na koji kontrola misije obrađuje komunikaciju sa svemirskim letjelicama - umjesto da resetira cijeli sustav za svaku transmisiju, održavaju kontinuirani rad dok obrađuju nove informacije.

Kreirajte funkciju koja hvata događaj slanja obrasca i izvlači korisnički unos:

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

U gore navedenom, mi smo:

  • Spriječili defaultno ponašanje slanja obrasca koje bi osvježilo stranicu
  • Izvukli vrijednosti korisničkog unosa iz polja za API ključ i regiju
  • Proslijedili podatke obrasca funkciji setUpUser() za obradu
  • Održali ponašanje aplikacije na jednoj stranici izbjegavajući ponovno učitavanje stranice

Zapamtite da vaša polja obrasca HTML-a uključuju atribut required, tako da preglednik automatski provjerava da korisnici unesu i API ključ i regiju prije nego što ova funkcija bude pokrenuta.

Postavljanje korisničkih preferencija

Funkcija setUpUser odgovorna je za spremanje korisničkih vjerodajnica i pokretanje prvog API poziva. Ovo stvara glatki prijelaz od postavljanja do prikazivanja rezultata.

function setUpUser(apiKey, regionName) {
	// Save user credentials for future sessions
	localStorage.setItem('apiKey', apiKey);
	localStorage.setItem('regionName', regionName);
	
	// Update UI to show loading state
	loading.style.display = 'block';
	errors.textContent = '';
	clearBtn.style.display = 'block';
	
	// Fetch carbon usage data with user's credentials
	displayCarbonUsage(apiKey, regionName);
}

Korak po korak, evo što se događa:

  • Spremanje API ključa i naziva regije u lokalnu pohranu za buduću upotrebu
  • Prikazivanje indikatora učitavanja kako bi se korisnici obavijestili da se podaci dohvaćaju
  • Brisanje svih prethodnih poruka o pogreškama s prikaza
  • Otkrivanje gumba za brisanje kako bi korisnici kasnije mogli resetirati svoje postavke
  • Pokretanje API poziva za dohvaćanje stvarnih podataka o ugljičnoj potrošnji

Ova funkcija stvara besprijekorno korisničko iskustvo upravljanjem i pohranom podataka i ažuriranjem korisničkog sučelja u jednoj koordiniranoj akciji.

Prikaz podataka o ugljičnoj potrošnji

Sada ćemo povezati vaše proširenje s vanjskim izvorima podataka putem API-ja. Ovo transformira vaše proširenje iz samostalnog alata u nešto što može pristupiti informacijama u stvarnom vremenu s interneta.

Razumijevanje API-ja

API-ji su način na koji različite aplikacije međusobno komuniciraju. Zamislite ih kao telegrafski sustav koji je povezivao udaljene gradove u 19. stoljeću - operateri su slali zahtjeve udaljenim stanicama i primali odgovore s traženim informacijama. Svaki put kad provjeravate društvene mreže, postavljate pitanje glasovnom asistentu ili koristite aplikaciju za dostavu, API-ji omogućuju te razmjene podataka.

Ključni koncepti o REST API-jima:

  • REST označava 'Representational State Transfer'
  • Koristi standardne HTTP metode (GET, POST, PUT, DELETE) za interakciju s podacima
  • Vraća podatke u predvidljivim formatima, obično JSON
  • Pruža dosljedne URL-based krajnje točke za različite vrste zahtjeva

CO2 Signal API koji ćemo koristiti pruža podatke o ugljičnoj intenzivnosti električnih mreža širom svijeta u stvarnom vremenu. Ovo pomaže korisnicima razumjeti utjecaj njihove potrošnje električne energije na okoliš!

💡 Razumijevanje asinkronog JavaScripta: Ključna riječ async omogućuje vašem kodu da istovremeno obrađuje više operacija. Kada zatražite podatke od servera, ne želite da cijelo proširenje zamrzne - to bi bilo kao da kontrola zračnog prometa zaustavi sve operacije dok čeka odgovor jednog aviona.

Ključne prednosti:

  • Održava responzivnost proširenja dok se podaci učitavaju
  • Omogućuje nastavak izvršavanja drugog koda tijekom mrežnih zahtjeva
  • Poboljšava čitljivost koda u usporedbi s tradicionalnim obrascima povratnih poziva
  • Omogućuje graciozno rukovanje pogreškama u mreži

Evo kratkog videa o async:

Async i Await za upravljanje obećanjima

🎥 Kliknite na sliku iznad za video o async/await.

Kreirajte funkciju za dohvaćanje i prikaz podataka o ugljičnoj potrošnji:

// Modern fetch API approach (no external dependencies needed)
async function displayCarbonUsage(apiKey, region) {
	try {
		// Fetch carbon intensity data from CO2 Signal API
		const response = await fetch('https://api.co2signal.com/v1/latest', {
			method: 'GET',
			headers: {
				'auth-token': apiKey,
				'Content-Type': 'application/json'
			},
			// Add query parameters for the specific region
			...new URLSearchParams({ countryCode: region }) && {
				url: `https://api.co2signal.com/v1/latest?countryCode=${region}`
			}
		});

		// Check if the API request was successful
		if (!response.ok) {
			throw new Error(`API request failed: ${response.status}`);
		}

		const data = await response.json();
		const carbonData = data.data;

		// Calculate rounded carbon intensity value
		const carbonIntensity = Math.round(carbonData.carbonIntensity);

		// Update the user interface with fetched data
		loading.style.display = 'none';
		form.style.display = 'none';
		myregion.textContent = region.toUpperCase();
		usage.textContent = `${carbonIntensity} grams (grams CO₂ emitted per kilowatt hour)`;
		fossilfuel.textContent = `${carbonData.fossilFuelPercentage.toFixed(2)}% (percentage of fossil fuels used to generate electricity)`;
		results.style.display = 'block';

		// TODO: calculateColor(carbonIntensity) - implement in next lesson

	} catch (error) {
		console.error('Error fetching carbon data:', error);
		
		// Show user-friendly error message
		loading.style.display = 'none';
		results.style.display = 'none';
		errors.textContent = 'Sorry, we couldn\'t fetch data for that region. Please check your API key and region code.';
	}
}

Razlaganje onoga što se ovdje događa:

  • Koristi moderni fetch() API umjesto vanjskih biblioteka poput Axiosa za čišći kod bez ovisnosti
  • Provodi pravilnu provjeru pogrešaka s response.ok kako bi se rano otkrili neuspjesi API-ja
  • Rukuje asinkronim operacijama s async/await za čitljiviji tijek koda
  • Autentificira se s CO2 Signal API-jem koristeći zaglavlje auth-token
  • Parsira JSON podatke odgovora i izvlači informacije o ugljičnoj intenzivnosti
  • Ažurira više elemenata korisničkog sučelja formatiranim podacima o okolišu
  • Pruža korisnički prihvatljive poruke o pogreškama kada API pozivi ne uspiju

Ključni moderni JavaScript koncepti demonstrirani:

  • Predlošci literala sa sintaksom ${} za čisto formatiranje stringova
  • Rukovanje pogreškama s try/catch blokovima za robusne aplikacije
  • Async/await obrazac za graciozno rukovanje mrežnim zahtjevima
  • Destrukturiranje objekata za izdvajanje specifičnih podataka iz odgovora API-ja
  • Lančanje metoda za višestruke manipulacije DOM-om

Ova funkcija demonstrira nekoliko važnih koncepata web razvoja - komunikaciju s vanjskim serverima, rukovanje autentifikacijom, obradu podataka, ažuriranje sučelja i graciozno rukovanje pogreškama. Ovo su temeljne vještine koje profesionalni programeri redovito koriste.

🎉 Što ste postigli: Kreirali ste proširenje za preglednik koje:

  • Povezuje se s internetom i dohvaća stvarne podatke o okolišu
  • Čuva korisničke postavke između sesija
  • Rukuje pogreškama graciozno umjesto da se ruši
  • Pruža glatko, profesionalno korisničko iskustvo

Testirajte svoj rad pokretanjem npm run build i osvježavanjem vašeg proširenja u pregledniku. Sada imate funkcionalni alat za praćenje ugljičnog otiska. Sljedeća lekcija će dodati funkcionalnost dinamičnih ikona kako bi se proširenje dovršilo.


Izazov GitHub Copilot Agent 🚀

Koristite Agent način rada za dovršavanje sljedećeg izazova:

Opis: Poboljšajte proširenje za preglednik dodavanjem poboljšanja u rukovanju pogreškama i značajki korisničkog iskustva. Ovaj izazov pomoći će vam da vježbate rad s API-jima, lokalnom pohranom i manipulacijom DOM-a koristeći moderne JavaScript obrasce.

Zadatak: Kreirajte poboljšanu verziju funkcije displayCarbonUsage koja uključuje: 1) Mehanizam ponovnog pokušaja za neuspjele API pozive s eksponencijalnim odgodama, 2) Validaciju unosa za kod regije prije nego što se izvrši API poziv, 3) Animaciju učitavanja s indikatorima napretka, 4) Predmemoriranje odgovora API-ja u lokalnoj pohrani s vremenskim oznakama isteka (predmemorija na 30 minuta), i 5) Značajku za prikaz povijesnih podataka iz prethodnih API poziva. Također dodajte odgovarajuće JSDoc komentare u stilu TypeScript-a za dokumentiranje svih parametara funkcije i tipova povratnih vrijednosti.

Saznajte više o Agent načinu rada ovdje.

🚀 Izazov

Proširite svoje razumijevanje API-ja istraživanjem bogatstva API-ja preglednika dostupnih za web razvoj. Odaberite jedan od ovih API-ja preglednika i izradite malu demonstraciju:

  • Geolocation API - Dohvatite trenutnu lokaciju korisnika
  • Notification API - Pošaljite obavijesti U ovoj lekciji ste naučili o LocalStorage i API-ima, oba vrlo korisna za profesionalnog web programera. Možete li razmisliti o tome kako ove dvije stvari rade zajedno? Razmislite o tome kako biste osmislili web stranicu koja bi pohranjivala stavke koje će koristiti API.

Zadatak

Usvojite API


Izjava o odricanju odgovornosti:
Ovaj dokument je preveden pomoću AI usluge za prevođenje Co-op Translator. Iako nastojimo osigurati točnost, imajte na umu da automatski prijevodi mogu sadržavati pogreške ili netočnosti. Izvorni dokument na izvornom jeziku treba smatrati autoritativnim izvorom. Za ključne informacije preporučuje se profesionalni prijevod od strane čovjeka. Ne preuzimamo odgovornost za nesporazume ili pogrešne interpretacije koje proizlaze iz korištenja ovog prijevoda.