Easy Weather check on JavaScript and Rails as Backend.
JC
Posted on November 4, 2021
So I made my fourth app Yay. It was challenging. It was hard. It took me a long time. Basically I build my Backend on Ruby on Rails and the Frontend on JS.
I decided to build an app that took data from the Open Weather map API. Why? Well I like weather stuff :)
This app was built to give a quick update of the weather either by your current location or any location you ask for.
So how do I build it?
The first step was to identify the API's to use:
so I signed for this awesome one:
- OPENWEATHERMAP. To get the good weather data. So all cool.
So let's write the code:
I needed to get the data for the weather first so I built my backend on rails and fetch the weather. I used rails to get the data and JSON to parse it.
class Location < ApplicationRecord
belongs_to :user
def self.search_location(location_query)
results = Geocoder.search(location_query)
if results === []
begin
raise Error
rescue Error => e
puts e.message
end
return
end
response = results.first.coordinates
lat = response[0]
lon = response[1]
self.search(lat, lon)
end
def self.location_query(location_query)
results = Geocoder.search(location_query)
response = results[0]
end
def self.search(lat, lon)
response = HTTParty.get("https://api.openweathermap.org/data/2.5/onecall?lat=#{lat}&lon=#{lon}&exclude=minutely&appid=#{ENV['API_KEY']}&units=metric")
data = JSON.parse(response.body)
end
etc..............
Once I located all data I needed for current weather I started building my app. I wanted to get the following results:
- Check the current weather at any location
Be able to give users the option to store a weather card on their accounts.
It will give the current temperature and conditions.
Fetch all this data and building my Frontend application with JavaScrip.
To fetch the data a create a Class API and add some async functions for this goal like so:
class Api {
constructor() {
this.baseURL = "http://localhost:7000/"
}
async fetchUsers() {
let response = await fetch(this.baseURL + `/users`)
let data = await response.json()
return data
}
async postUser(email, password, registerUser) {
let data = {
user: {
email,
password
}
}
let configObj = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(data)
}
const fetchURL = registerUser ? `${this.baseURL}users` : `${this.baseURL}login`;
fetch(fetchURL, configObj)
.then(resp => resp.json())
.then(data => {
if (data.errors) {
email = '';
password = '';
alert(data.errors);
} else {
window.sessionStorage.currentUsername = data.user.username;
window.sessionStorage.currentUserId = data.user.id;
loginButton.remove();
userLogin.remove();
welcomeLoggin();
allLocation(data.user.id);
displayForm()
}
});
}
async createUser(username, email, password, registerUser) {
let data = {
user: {
username,
email,
password
}
}
console.log(data)
let configObj = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(data)
}
const fetchURL = registerUser ? `${this.baseURL}login` : `${this.baseURL}users`;
fetch(fetchURL, configObj)
.then(resp => resp.json())
.then(data => {
if (data.errors) {
username = '';
email = '';
password = '';
alert(data.errors);
} else {
window.sessionStorage.currentUsername = data.user.username;
window.sessionStorage.currentEmail = data.user.email;
window.sessionStorage.currentUserId = data.user.id;
loginButton.remove();
userLogin.remove();
welcomeLoggin();
allLocation(data.user.id);
displayForm()
}
});
}
async fetchURL() {
const fetchURL = registerUser ? `${this.baseURL}users` : `${this.baseURL}login`;
let response = await fetch(fetchURL)
console.log(response)
}
"yeah" you are ready to check the weather at any location.
Well not so Easy. I wanted to make it more user friendly so added some extras for users on JS. So I created an User Class and a Basic Authentication connected to my backend on Rails...
class Weather{
constructor(){
this.login = new Login()
}
}
..........
async function validateLoginForm() {
const loginemail = document.getElementById("logEmail").value;
const loginpassword = document.getElementById("logPassword").value;
if (loginemail == "" || loginpassword == "") {
document.getElementById("errorMsg").innerHTML = "Please fill the required fields"
return false;
}
else if (loginpassword.length < 2) {
document.getElementById("errorMsg").innerHTML = "Your password must include atleast 8 characters"
return false;
}
else {
const data = await api.postUser(loginemail, loginpassword, false);
// alert("Successfully logged in");
return true;
}
}
.. Etc
All right. Once my app was running and the hard part of the project was done I decided to add a face for each weather query... meaning a "Weather Card" ;)
Well I know it is a lot but It was fun. What I learn:
- APIs can be tricky and hard to work with but once you are in the Matrix It becomes easier.
- JS could be really challenging fetching elements from and API. Using Classes simplify the job.
Thanks for reading ..
So long
Posted on November 4, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.