This weather app was my first PWA project which I decided to write in Ionic, it made a change from doing another todo app!
Project Writeup
https://www.danidean.co.uk/portfolio/pweathera/
Project
I started off this project by following Ionic’s quickstart guide and creating a blank new Ionic project with ionic start weather-pwa blank --type vue. I wanted to keep to JavaScript so I removed TypeScript. Once the app was up and running I registered an account with OpenWeatherMap to use their API to get the weather data I needed for the app as well as registering an account with Unsplash to use their API for getting an image to use in the app that fits with the weather result.
I set out some basic components such as cards to display data and a location search bar in the footer.
The first focus was calling the weather API to get some data back to display, I set the location variable to london so when the app initially loaded it would have data displaying on the screen (as part of a future improvement I would allow the user to set a location).
Within the data I set all the variables I planned to use.
data () {
return {
search: 'london',
units: 'metric',
weather: {
icon: '',
image_user: '',
image_user_link: '',
sys: {
sunrise: '',
sunset: ''
},
main: {
humidity: '',
temp: '',
pressure: ''
},
weather: [{
main: '',
description: ''
}],
wind: {
speed: ''
}
}
}
}
In the created hook I am calling a getWeather function.
created() {
this.getWeather();
}
In the getWeather function I am using the axios module to call the weather api, setting the query, units and api key params. In the response of this API call I am setting all the variables and then calling the getImage function. Also as you can see near the end of the response I am getting the sunrise and sunset times and using a time function to format these into something readable.
methods: {
getWeather() {
axios.get("https://api.openweathermap.org/data/2.5/weather?q="+this.$data.search+"&units="+this.$data.units+"&appid=APIKEY")
.then(response => {
this.$data.weather = response.data;
this.$data.weather.icon = "https://openweathermap.org/img/wn/"+response.data.weather[0].icon+".png";
this.$data.weather.sys.sunrise = this.time(response.data.sys.sunrise);
this.$data.weather.sys.sunset = this.time(response.data.sys.sunset);
this.getImage();
})
.catch(err => {
console.log('error', err);
});
}
}
In the getImage function I am calling the Unsplash API by sending the weather description returned from the getWeather function.
getImage() {
axios.get("https://api.unsplash.com/search/photos?client_id=APIKEY&page=1&per_page=1&orientation=squarish&query="+this.$data.weather.weather[0].description)
.then(response => {
this.$data.weather.image = response.data.results[0].urls.small;
this.$data.weather.image_user = response.data.results[0].user.name;
this.$data.weather.image_user_link = response.data.results[0].user.links.html+"?utm_source=weather_pwa&utm_medium=referral";
})
.catch(err => {
console.log('error', err);
});
}
When all the data was successfully being returned and displayed I committed my code and deployed the app to Netlify. Once that was done I then added the PWA functionality by running the command vue add pwa. Vue adds the necessary files and imports them such as the registerServiceWorker.js and manifest.json.