Get Weather Info in Apex Rest API

by Rijwan Mohmmed
0 comment
Display-Weather-Info-in-LWC-by-Apex

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 :

  1. Lightning web component for set and display weather info.
  2. Rest API callout in apex class.
  3. Validation on LWC field before submit to apex.
  4. Create JSON Class according API response so we can parse the data.
  5. 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 :

You may also like

Leave a Comment