Your First Progressive Web Application (5)
Progressive web applications will launch quickly and be available immediately. In the current state (step-04), our weather app starts quickly, but is not available. Because there's no data yet. We're going to use an AJAX request to fetch the data, but this will result in an extra request and make the initial load time longer. But still provide real data on the first load.
For this code lab, we will simulate the server injecting the weather forecast directly into the JavaScript, but during the production application, the latest weather forecast data will be injected by the server based on the geographic location of the user's IP address.
The code already contains data and we're going to inject it, which is this initialWeatherForecast method, we start using the next step.
But how do we know when to display this information, which may not be relevant for future loading when the weather app pulls it from the cache? When the user loads the app on a subsequent visit, they may have changed cities, so we need to load information about those cities, not necessarily the one they looked up the first time.
User preferences (such as a list of cities to which the user has subscribed) should be stored locally using IndexedDB or another fast storage mechanism. To make this code experiment as simple as possible, we used localStorage , which is not ideal for production applications, as it is a blocking synchronous storage mechanism that can be very slow on some devices.
Additional Tips : replacement with idblocalStorage to achieve, ensuring localForage does a simple wrapper for idb.
First, we add the required code to save the user settings in your code by finding the TODO note shown below.
// TODO add saveSelectedCities function here
Add the following code below the note.
// Save list of cities to localStorage. app.saveSelectedCities = function() { var selectedCities = JSON.stringify(app.selectedCities); localStorage.selectedCities = selectedCities; };
Next, we add startup code to check if the user has any saved cities and render them, or use the injected data. The following notes were found.
// TODO add startup code here
Add the following code below the note:
/************************************************************************ * * Code required to start the app * * NOTE: To simplify this codelab, we've used localStorage. * localStorage is a synchronous API and has serious performance * implications. It should not be used in production applications! * Instead, check out IDB (https://www.npmjs.com/package/idb) or * SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c) ************************************************************************/ app.selectedCities = localStorage.selectedCities; if (app.selectedCities) { app.selectedCities = JSON.parse(app.selectedCities); app.selectedCities.forEach(function(city) { app.getForecast(city.key, city.label); }); } else { /* The user is using the app for the first time, or the user has not * saved any cities, so show the user some fake data. A real app in this * scenario could guess the user's location via IP lookup and then inject * that data into the page. */ app.updateForecastCard(initialWeatherForecast); app.selectedCities = [ {key: initialWeatherForecast.key, label: initialWeatherForecast.label} ]; app.saveSelectedCities(); }
The startup code checks to see if any cities are saved in local storage. If yes, parses the locally stored data and then displays the weather forecast card for each saved city. If no, the startup code simply uses the false prediction data and saves it as the default city.
Finally, you need to modify the "Add City" button procedure to save the selected city to local storage
Update your butAddCity Click on the program to make it the same as the code below :
document.getElementById('butAddCity').addEventListener('click', function() { // Add the newly selected city var select = document.getElementById('selectCityToAdd'); var selected = select.options[select.selectedIndex]; var key = selected.value; var label = selected.textContent; if (!app.selectedCities) { app.selectedCities = []; } app.getForecast(key, label); app.selectedCities.push({key: key, label: label}); app.saveSelectedCities(); app.toggleAddDialog(false); });
Added app.selectedCities is initialized, and if it does not exist, the call to app.selectedCities.push() harmony app.saveSelectedCities() method。