This is the conclusion in a four part series on developing a simple Fitbit app. If you need to catch up, you can find Part 3 here. So far, we have retrieved the user’s location, used it to query weather information from the internet, and sent the forecast to the watch. All we need to do now is to display it in a way that the user can appreciate.
- Get some icons for various weather conditions. You can find these on various sites, or included in the project repository (in the resources directory).
- Open the index.view file. This file contains <svg> tags that we will use to build the user interface.
- The view below contains icon placeholders for the current day and a three-day forecast. The high and low temperatures are included for each day. Please customize this interface to your own desire!
<svg class="background">
# Today's Forecast
<image id="today" x="20%+5" y="5%" width="33%" height="33%" pointer-events="visible"/>
<text id="hightoday" x="60%" y="20%" class="today">-</text>
<text id="lowtoday" x="60%" y="30%" class="today">-</text>
<text id="forecasttoday" x="50%" y="50%+15" class="forecast">-</text>
# 3-Day Forecast
<image id="tomorrow" x="1%" y="55%" width="25%" height="25%"/>
<text id="highday1" x="15%" y="82%" class="forecast">-</text>
<text id="lowday1" x="15%" y="90%" class="forecast">-</text>
<image id="dayafter" x="36%" y="55%" width="25%" height="25%"/>
<text id="highday2" x="50%" y="82%" class="forecast">-</text>
<text id="lowday2" x="50%" y="90%" class="forecast">-</text>
<image id="finalday" x="72%" y="55%" width="25%" height="25%"/>
<text id="highday3" x="85%" y="82%" class="forecast">-</text>
<text id="lowday3" x="85%" y="90%" class="forecast">-</text>
</svg>
- Edit the styles.css file for the view you just created. Here, you can customize the app background, text font size, and more.
.background {
viewport-fill: black;
}
.today {
fill: white;
font-size: 32;
font-family: System-Regular;
font-weight: bold;
text-anchor: middle;
text-length: 99;
}
.forecast {
fill: white;
font-size: 24;
font-family: System-Regular;
font-weight: bold;
text-anchor: middle;
text-length: 99;
}
- Edit the app index.js file.
- If a file (forecast) has been received: get the elements from the canvas and set them with the appropriate icons or text.
// Event occurs when new file(s) are received
inbox.onnewfile = () => {
console.log("New file!");
let fileName;
// If there is a file, move it from staging into the application folder
fileName = inbox.nextFile();
if (fileName) {
console.log(`Received File: <${fileName}>`);
weather = fs.readFileSync(fileName, "ascii");
// Get Text Elements
let hightoday = document.getElementById("hightoday");
let lowtoday = document.getElementById("lowtoday");
let forecast = document.getElementById("forecasttoday");
let hightomorrow = document.getElementById("highday1");
let lowtomorrow = document.getElementById("lowday1");
let highday2 = document.getElementById("highday2");
let lowday2 = document.getElementById("lowday2");
let highday3 = document.getElementById("highday3");
let lowday3 = document.getElementById("lowday3");
// Get Image Elements
let today = document.getElementById("today");
let tomorrow = document.getElementById("tomorrow");
let dayafter = document.getElementById("dayafter");
let finalday = document.getElementById("finalday");
hightoday.text = `${JSON.parse(weather)[0].temperature} F`;
lowtoday.text = `${JSON.parse(weather)[1].temperature} F`;
forecast.text = `${JSON.parse(weather)[0].shortForecast}`;
hightomorrow.text = `${JSON.parse(weather)[2].temperature}`;
lowtomorrow.text = `${JSON.parse(weather)[3].temperature}`;
highday2.text = `${JSON.parse(weather)[4].temperature}`;
lowday2.text = `${JSON.parse(weather)[5].temperature}`;
highday3.text = `${JSON.parse(weather)[6].temperature}`;
lowday3.text = `${JSON.parse(weather)[7].temperature}`;
today.href = iconSelection(`${JSON.parse(weather)[0].shortForecast}`);
tomorrow.href = iconSelection(`${JSON.parse(weather)[2].shortForecast}`);
dayafter.href = iconSelection(`${JSON.parse(weather)[4].shortForecast}`);
finalday.href = iconSelection(`${JSON.parse(weather)[6].shortForecast}`);
}
};
- Add an icon selection function to display a visual for each type of weather. (You can add more than what is listed here!)
function iconSelection(forecastToday) {
switch (forecastToday) {
case "Areas Of Fog then Mostly Sunny":
return "mostly_sunny.png";
break;
case "Areas Of Fog then Partly Sunny":
return "mostly_sunny.png";
break;
case "Chance Rain Showers":
return "chance_showers.png";
break;
case "Chance Snow Showers":
return "chance_showers.png";
break;
case "Mostly Clear":
return "mostly_sunny.png";
break;
case "Mostly Cloudy":
return "mostly_sunny.png";
break;
case "Mostly Sunny":
return "mostly_sunny.png";
break;
case "Partly Sunny":
return "mostly_sunny.png";
break;
case "Partly Sunny then Slight Chance Snow Showers":
return "chance_showers.png";
break;
case "Sunny":
return "sunny.png";
break;
default:
return "mostly_sunny.png";
}
}
- Run the App!

So far, the App displays the weather very nicely if it is available. But, the user will not be notified if any errors occur.
- Add a try/catch block in the remoteAccess.js file to send an empty JSON object if the forecast cannot be retrieved from the weather service. (e.g., The user is not in the United States)
try {
console.log(forecasturl)
var response = await fetch(forecasturl)
var forecast = (await response.json()).properties.forecast // Parse the returned object
console.log("Current location forecast: " + forecast)
response = await fetch(forecast)
forecast = (await response.json()).properties.periods // Parse the returned object
} catch (error) {
console.log(error);
return JSON.parse("{}")
}
- Add another try/catch block in the app index.js file to display a helpful message to the user if the forecast is unavailable in their current location.
try {
hightoday.text = `${JSON.parse(weather)[0].temperature} F`;
lowtoday.text = `${JSON.parse(weather)[1].temperature} F`;
forecast.text = `${JSON.parse(weather)[0].shortForecast}`;
hightomorrow.text = `${JSON.parse(weather)[2].temperature}`;
lowtomorrow.text = `${JSON.parse(weather)[3].temperature}`;
highday2.text = `${JSON.parse(weather)[4].temperature}`;
lowday2.text = `${JSON.parse(weather)[5].temperature}`;
highday3.text = `${JSON.parse(weather)[6].temperature}`;
lowday3.text = `${JSON.parse(weather)[7].temperature}`;
today.href = iconSelection(`${JSON.parse(weather)[0].shortForecast}`);
tomorrow.href = iconSelection(`${JSON.parse(weather)[2].shortForecast}`);
dayafter.href = iconSelection(`${JSON.parse(weather)[4].shortForecast}`);
finalday.href = iconSelection(`${JSON.parse(weather)[6].shortForecast}`);
} catch (error) {
console.log(error);
forecast.text = "Forecast unavailable.";
}
Thank you for following along with the tutorial! You can find Part 4 source code in the project repository. I hope this tutorial was helpful.
What’s next?
- Expand this App. How can you add additional weather information? What additional screens should be included?
- Use your knowledge of geolocation, remote access, and UI to develop more apps!
Leave a comment