Design-build application architect

I've worked on dozens of sites/applications both as a designer and developer in Angular, React, Vue, Ruby on Rails and PHP. Starting my career in user experience design, I am particularly good at analyzing a problem and finding the most efficient solution.

See my recommendations on LinkedIn. Or view my most recent work.

mark [at] markmakes [dot] com

©Latest Article

Mar 22, 2019 · 5 min read #Angular

Building a weather app in Angular

A few years back when I was more of a UX designer, I created a weather app mockup that I believed I would use personally if developed. At that time, weather apps were pretty lackluster and/or suffered from information overload.

TL:DR; here's the weather app demo and the open source code.

weather app mockup
Feel free to like it on Dribbble.

So while I had a bit of time this weekend, I decided to create an MVP of this mockup using Angular. My first step was to find a solid weather API that was free and returned the information needed for my app. I had a few choices.

  • Accuweather
  • DarkSky
  • OpenWeather

Looking back in hindsight, I should have used DarkSky entirely, but instead I used a combination of OpenWeather and DarkSky only because OpenWeather allows unlimited calls as long as you don't have more than 1000 per minute, whereas DarkSky charges per call.

Gathering Data

Simple XMLHttpRequests are extremely useful to quickly grab data and use it in Angular. Sure there are times I need observables, but for now this will do. You can also convert this into a promise if needed.

const ajax1 = new XMLHttpRequest();

ajax1.open('GET', 'https://api.openweathermap.org/data/2.5/weather?q=Houston&appid=' + this.api, false);
ajax1.send();

this.city1 = JSON.parse(ajax1.responseText);

I make 4 separate calls for the 4 cities I'm statically declared. If I'm so inclined to develop this MVP further, I'll make the cities configurable with localStorage so we don't have to create a backend.

This GET request for weather by city returns a good amount of data that I need to transform in order for it to be usable for the end user. This includes converting:

  • Kelvin -> Fahrenheit
  • Meteorological wind degrees -> cardinal directions
  • Epoch UTC time
  • Temperature to appropriate CSS background colors

In a previous article about dynamically changing SASS variables with Angular I talked about how HostBinding to style allows you to set SASS variables ready to be used in your SCSS file. I did that here, but took it a single step further and changed the hue of the background color by the temperature that was returned in the API.

$temp: var(--temp);

.city {
  background-color: hsl($temp, 80%, 40%);
}

Now every city will get a unique background color according to its temperature. Also the background watermark of each city will correspond appropriately (rain, snow, clouds, sun, etc.).

Creating the forecast and displaying DarkSky maps

To keep my API calls lite, I only make the additional call to get the forecast once a user has selected a city. The array that is returned is far more information than I need as it returns every forecast n + 3 hours into the future, so below you'll see in the loop that I grab every 8th element.

ajax.open('GET', 'https://api.openweathermap.org/data/2.5/forecast?q=' + this.city.name + '&appid=' + this.api, false);

this.forecast = JSON.parse(ajax.responseText);

if (this.forecast.list) {
  let i;
  for (i = 7; i < this.forecast.list.length; i = i + 8) {
    this.fiveDay.push(this.forecast.list[i]);
  }
}

Then after that I utilize the DarkSky map embed with the latitude and longitude returned from OpenWeather to render the radar view. Angular has a lot of cross-site scripting security built-in, so I have to use PostScribe to allow the document.write function within the DarkSky embed to fire and therefore render to the DOM.

this.link = 'https://darksky.net/map-embed/@radar,' + this.city.coord.lat + ',' + this.city.coord.lon + ',10.js?embed=true&timeControl=false&fieldControl=false&defaultField=radar';
const script = '';
postscribe('#darkSky', script);

After that, it's just a matter of writing some basic CSS to give the asthetics a nice touch and we're done. Let me know if you have any questions in the comments below! Or clone the repo and play with it yourself.

&More Articles

March 14, 2019 · 3 min read

Creative ways to monetize your app

Advertising will never account to a substantial amount of revenue. It can be a part of your overall monetization strategy...