Hello friends, today we will discuss Get Weather Info in Apex Rest API Salesforce. Weather info is a very necessary thing right now so we can check the temperature, pressure, humidity, etc. There are paid/non-paid multiple APIs for Weather info on the internet. So we can easily get info by putting city information.
Check this: Implement Basic Auth Integration(Rest API) in Apex Salesforce
Highlights Point :
- Lightning web component for set and display weather info.
- Rest API callout in apex class.
- Validation on LWC field before submit to apex.
- Create JSON Class according API response so we can parse the data.
- Imperate apex call in LWC.
Step 1: In this step, we set up OpenWeatherMap account. You can log in via Gmail. After creating an account go to your profile name and click API Keys. Set and copy the API key for further.
Step 2: Set up the remote setting of this Endpoint URL GO Setup > Remote Site Settings > Click New Remote Site and create new records by filling Endpoint and name. EndPoint ==> https://api.openweathermap.org/data/2.5/weather
Step 3: In this step, we create an Apex class for writing logic for fetching weather info. We call callout in the apex method by passing city zip code and country code in Endpoint. Also, we create a JSON parser class to parse the JSON data in the apex List so it will be easy for us to read the data.
WeatherCtrl.cls :
public class WeatherCtrl {
@AuraEnabled
public static wrapperData fetchWeatherInfo(String zipCode, String countryCode){
String APIKey = 'a0044bd1008903b54a7e61bc07d1de24';
//authurize this url in remote setting
//String endPoint = 'https://api.openweathermap.org/data/2.5/weather?q=' + city + '&units=metric&appid=' +appId;
String endPoint = 'https://api.openweathermap.org/data/2.5/weather?zip=' + zipCode + ',' + countryCode +'&appid=' +APIKey;
HttpRequest request = new HttpRequest();
HttpResponse response = new HttpResponse();
Http http = new Http();
request.setEndpoint(endPoint);
request.setMethod('POST');
response = http.send(request);
if (response.getStatusCode() == 200) {
String jsonResponse = response.getBody();
fromJSON jsonParseData = (fromJSON)parse(jsonResponse);
wrapperData wrpData = new wrapperData(jsonParseData);
System.debug('Response-' + jsonParseData);
return wrpData;
} else{
throw newMessageException('Error : Please check zipcode or country');
}
}
private static AuraHandledException newMessageException(String message) {
AuraHandledException e = new AuraHandledException(message);
e.setMessage(message);
return e;
}
public class wrapperData{
@AuraEnabled
public String name;
@AuraEnabled
public Double temp;
@AuraEnabled
public Integer sunset;
@AuraEnabled
public Integer sunrise;
@AuraEnabled
public Integer humidity;
@AuraEnabled
public Integer pressure;
public wrapperData(fromJSON parseData){
cls_main te = parseData.main;
this.name = parseData.name;
this.temp = te.temp;
this.humidity = te.humidity;
this.pressure = te.pressure;
this.sunrise = parseData.sys.sunrise;
this.sunset = parseData.sys.sunset;
}
}
public class fromJSON{
public cls_coord coord;
public cls_weather[] weather;
public String base; //stations
public cls_main main;
public Integer visibility; //10000
public cls_wind wind;
public cls_clouds clouds;
public Integer dt; //1640777807
public cls_sys sys;
public Integer timezone; //-18000
public Integer id; //0
public String name; //Norcross
public Integer cod; //200
}
public class cls_coord {
public Double lon; //-84.0379
public Double lat; //33.9604
}
public class cls_weather {
public Integer id; //804
public String main; //Clouds
public String description; //overcast clouds
public String icon; //04n
}
public class cls_main {
public Double temp; //291.86
public Double feels_like; //292.06
public Double temp_min; //290.15
public Double temp_max; //293.27
public Integer pressure; //1013
public Integer humidity; //87
}
public class cls_wind {
public Double speed; //0.89
public Integer deg; //225
public Double gust; //1.79
}
public class cls_clouds {
public Integer all; //90
}
public class cls_sys {
public Integer type; //2
public Integer id; //2032059
public String country; //US
public Integer sunrise; //1640781647
public Integer sunset; //1640817337
}
public static fromJSON parse(String json){
return (fromJSON) System.JSON.deserialize(json, fromJSON.class);
}
}
Step 4: In this step, we will create a Lightning Web Component so we can feed the data of city zip code and Country and show it on the same page after submitting. We also show an error message toast if the country code or zipcode is wrong.
WeatherLwcComponent.Html :
<template>
<!-- loader -->
<div if:true={showSpinner}>
<lightning-spinner
alternative-text="Loading..." variant="brand">
</lightning-spinner>
</div>
<!------------->
<div class="slds-tabs_card">
<div class="slds-page-header">
<div class="slds-page-header__row">
<div class="slds-page-header__col-title">
<div class="slds-media">
<div class="slds-media__figure">
<span class="slds-icon_container slds-icon-standard-opportunity">
<lightning-icon icon-name="standard:recipe" alternative-text="recipe" title="recipe"></lightning-icon>
</span>
</div>
<div class="slds-media__body">
<div class="slds-page-header__name">
<div class="slds-page-header__name-title">
<h1>
<span>Call Parent Method From Child Component LWC</span>
<span class="slds-page-header__title slds-truncate" title="Recently Viewed">TechDicer</span>
</h1>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> <br/>
<lightning-card title="City Info to Fetch Weather" icon-name="standard:address">
<div class="slds-var-p-around_small">
<lightning-layout multiple-rows>
<lightning-layout-item padding="around-small" size="12" medium-device-size="12" large-device-size="12">
<lightning-combobox name="country" class="fieldvalidate"
label="Country Code" options={countryOptions} required>
</lightning-combobox>
<lightning-input name="pincode" class="fieldvalidate" type="number"
label="Pin/Zip Code" min="1000" max="999999"
message-when-range-overflow="Please enter a correct pincode"
message-when-range-underflow="Please enter a correct pincode/Zipcode" required>
</lightning-input>
</lightning-layout-item>
<lightning-layout-item size="12" class="slds-var-p-top_small">
<lightning-button class="slds-align_absolute-center" variant="brand" label="Submit"
onclick={handleValidation}></lightning-button>
</lightning-layout-item>
</lightning-layout>
</div>
</lightning-card><br/>
<lightning-card title="City Weather Info" icon-name="utility:salesforce1">
<div class="slds-var-p-around_small">
<div class="slds-p-horizontal_small">
<div class="slds-form" role="list">
<div class="slds-form__row">
<div class="slds-form__item" role="listitem">
<div
class="slds-form-element slds-form-element_edit slds-form-element_readonly slds-form-element_stacked slds-hint-parent">
<span class="slds-form-element__label">City Name</span>
<div class="slds-form-element__control">
<div class="slds-form-element__static">
{result.name}
</div>
</div>
</div>
</div>
<div class="slds-form__item" role="listitem">
<div
class="slds-form-element slds-form-element_edit slds-form-element_readonly slds-form-element_stacked slds-hint-parent">
<span class="slds-form-element__label">City Temperature</span>
<div class="slds-form-element__control">
<div class="slds-form-element__static">
{result.temp} celsius
</div>
</div>
</div>
</div>
</div>
<div class="slds-form__row">
<div class="slds-form__item" role="listitem">
<div
class="slds-form-element slds-form-element_edit slds-form-element_readonly slds-form-element_stacked slds-hint-parent">
<span class="slds-form-element__label">Sunrise</span>
<div class="slds-form-element__control">
<div class="slds-form-element__static">
{result.sunrise}
</div>
</div>
</div>
</div>
<div class="slds-form__item" role="listitem">
<div
class="slds-form-element slds-form-element_edit slds-form-element_readonly slds-form-element_stacked slds-hint-parent">
<span class="slds-form-element__label">Sunset</span>
<div class="slds-form-element__control">
<div class="slds-form-element__static">
{result.sunset}
</div>
</div>
</div>
</div>
</div>
<div class="slds-form__row">
<div class="slds-form__item" role="listitem">
<div
class="slds-form-element slds-form-element_edit slds-form-element_readonly slds-form-element_stacked slds-hint-parent">
<span class="slds-form-element__label">Pressure</span>
<div class="slds-form-element__control">
<div class="slds-form-element__static">
{result.pressure}
</div>
</div>
</div>
</div>
<div class="slds-form__item" role="listitem">
<div
class="slds-form-element slds-form-element_edit slds-form-element_readonly slds-form-element_stacked slds-hint-parent">
<span class="slds-form-element__label">Humidity</span>
<div class="slds-form-element__control">
<div class="slds-form-element__static">
{result.humidity}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</lightning-card>
</template>
WeatherLwcComponent.JS :
import { LightningElement } from 'lwc';
import fetchWeatherInfo from "@salesforce/apex/WeatherCtrl.fetchWeatherInfo";
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class WeatherLwcComponent extends LightningElement {
countryOptions = [
{ "label": "India", "value": "IN" },
{ "label": "USA", "value": "US" },
{ "label": "Turkey", "value": "TR" },
{ "label": "Australia", "value": "AU" }
];
countryCode;
zipCode;
showSpinner = false;
result = {};
//check field validation
handleCheckValidation() {
let isValid = true;
let inputFields = this.template.querySelectorAll('.fieldvalidate');
inputFields.forEach(inputField => {
if(!inputField.checkValidity()) {
inputField.reportValidity();
isValid = false;
}
if(inputField.name == "country"){
this.countryCode = inputField.value;
} else if(inputField.name == "pincode"){
this.zipCode = inputField.value;
}
});
return isValid;
}
handleValidation(event) {
if(this.handleCheckValidation()) {
this.handleSpinner();
//send data to server side to check wetaher
fetchWeatherInfo({zipCode : this.zipCode, countryCode : this.countryCode})
.then(result => {
//do something
console.log(result.name);
result.temp = (result.temp - 274.15).toFixed(2);
result.sunset = this.convertUnixToTime(result.sunset);
result.sunrise = this.convertUnixToTime(result.sunrise);
this.result = result;
this.handleSpinner();
})
.catch((error) => {
//Let's send the user a toast with our custom error message
const evt = new ShowToastEvent({
title: "Yikes!",
message: error.body.message,
variant: "error",
});
this.dispatchEvent(evt);
this.handleSpinner();
})
}
}
convertUnixToTime(unixtimestamp){
console.log(unixtimestamp);
var dt = unixtimestamp * 1000;
var myDate = new Date(dt);
console.log(myDate);
return(myDate.toLocaleString());
}
handleSpinner(){
this.showSpinner = !this.showSpinner;
}
}
WeatherLwcComponent.JS-meta.xml :
<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Output :