I am new to Lightning. I am trying to build a lightning component which would display the weather report. I am able to get the values in my debug log from my apex class. However, the same values are not populating on my Lightning component. Please refer to the codes below:
Apex class:
public virtual class WeatherUtil {
private static final String API_KEY = 'a032cd22e82569598abe1dced7625435';
public class Weather {
public String imageUrl { get; set; } // image.url
public String imageTitle { get; set; } // image.title
public String imageLink { get; set; } // image.link
public String displayLocation { get; set; } // display_location.full
public String weather {get;set;}
public String observationTime { get; set; } // observation_time
public String currentWeather { get; set; } // weather
public String currentTempF { get; set; } // temp_f
public String currentTempC { get; set; } // temp_c
public String currentWind { get; set; } // wind_string
public String feelsLikeF { get; set; } // feelslike_f
public String feelsLikeC { get; set; } // feelslike_c
public String pressure {get;set;}
public String isDay {get;set;}
public String weatherIconUrl { get; set; } // icon_url
}
// this method is to be used in Lightning Components (non record based view)
@AuraEnabled
public static String getLocalWeather(String state, String cityName) {
WeatherUtil.Weather weather = new WeatherUtil.Weather();
String result = makeCallout();
System.debug('result 100000' +result);
// return the serialized weather wrapper class, or null
return result.equalsIgnoreCase('success!') ? JSON.serialize(weather) : null;
//return result;
}
@AuraEnabled
// Method to perform callouts
public static String makeCallout(){
String State = 'West Bengal';
String city = 'Kolkata';
WeatherUtil.Weather weather1 = new WeatherUtil.Weather();
// define a response to caller
String outcomeMsg;
// define basic information for later, store these in a protected custom setting
// String endpoint = 'http://api.weatherstack.com'; // be sure this is configured in "Remote Site Settings"
// String resource = '/api/' + API_KEY + '/conditions/q/' + state + '/' + cityName.replace(' ', '_') + '.json';
String endpoint = 'http://api.weatherstack.com/current?access_key =a032cd22e82569598abe1dced7625435&query=Kolkata';
//String endpoint = 'http://api.weatherstack.com/forecast?access_key=a032cd22e82569598abe1dced7625435&query=Kolkata';
// String endpoint = 'http://api.weatherstack.com/autocomplete?access_key=a032cd22e82569598abe1dced7625435&query=Kolkata';
String method = 'GET';
// System.debug('resource '+resource);
// System.debug('Endpoint & Resource:::' + endpoint + resource);
// check to ensure a callout can be performed using the Limits class.
// This is 100 callouts per execution as of Spring 16 release
if (Limits.getCallouts() >= Limits.getLimitCallouts()) {
System.debug('Testing 200000');
outcomeMsg = 'Maximum number of callouts has been reached.';
// configure and perform the callout
} else {
System.debug('Testing 300000');
// define transaction variables
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http h = new Http();
// Configure the request
req.setEndpoint(endpoint);
req.setMethod(method);
req.setTimeout(120000);
// Configure standard headers
req.setHeader('Accept', '*/*');
// This tells the API that we are sending and receiving the data as a JSON object
req.setHeader('Content-Type', 'application/json');
System.debug('req :::::'+req);
// Additional headers may be needed / Refer to the API documentation.
// Use a service like runscope.com to test everything ahead of time.
// Set the body json with the description parameter, basically a string with a key value pair construction.
// This will look very different for each integration resource.
// Some APIs don't use a body to take the request,
// they may simply take additional resources "/resource/order/Ord#" in the URI
// or parameters "resource/?orderId=133" in the URI
// this integration doesn't require this, however yours might so I've left this here as an example
//req.setBody('{"text" : "' + description + '"}');
// Attempt the callout - create return error on exception
try {
// Perform callout and set response
res = h.send(req);
System.debug('res '+res);
//System.debug('res.getBody() '+res.getBody());
System.debug('resBody '+res.getBody());
System.debug('resStatus '+res.getStatus());
JSONParser parser = JSON.createParser(res.getBody());
System.debug('parser :::'+parser);
//System.debug('resHttp '+res.HttpResponse());
// check response
if ((res.getStatusCode() == 200 || res.getStatusCode() == 201) && res.getBody() != null) {
System.debug('Testing 500000');
// Deserialize the response untyped
Map<String, Object> untypedMap = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
System.debug('untypedMap '+untypedMap);
System.debug('untypesMapcontains :::'+untypedMap.containsKey('current_observation'));
System.debug('untypesMapcontains1 :::'+untypedMap.containsKey('response'));
System.debug('untypesMapcontains2 :::'+untypedMap.containsKey('results'));
System.debug('untypesMapcontains3 :::'+untypedMap.containsKey('current_location'));
System.debug('untypesMapcontains5 :::'+untypedMap.containsKey('request'));
System.debug('untypesMapcontains3 :::'+untypedMap.containsKey('current'));
System.debug(res.getBody());
// Check success of deserialization
if (untypedMap.containsKey('current')) {
System.debug('Entered in if');
// The deserialized response contains the expected key!
outcomeMsg = 'Success!';
Map<String,Object> currentWeather = (Map<String,Object>)untypedMap.get('current');
System.debug('currentWeather :::::'+currentWeather);
if (currentWeather.containsKey('image')) {
Map<String,Object> image = (Map<String,Object>)currentWeather.get('image');
weather1.imageUrl = (String)image.get('url'); // image.url
weather1.imageTitle = (String)image.get('title'); // image.title
weather1.imageLink = (String)image.get('link'); // image.link
}
if (currentWeather.containsKey('display_location')) {
Map<String,Object> displayLocation = (Map<String,Object>)currentWeather.get('display_location');
weather1.displayLocation = (String)displayLocation.get('full'); // display_location.full
}
weather1.observationTime = (String)currentWeather.get('observation_time'); // observation_time
weather1.currentWeather = (String)currentWeather.get('weather');
System.debug('weather.currentWeather :::'+weather1.currentWeather);
weather1.currentWind = (String)currentWeather.get('wind_string'); // wind_string
// round the temperatures before storing them
//Decimal tempF = (Decimal)currentWeather.get('temp_f');
// weather1.currentTempF = String.valueOf(tempF.round()); // temp_f
Decimal tempC = (Decimal)currentWeather.get('temperature');
System.debug('tempC :::'+tempC);
weather1.currentTempC = String.valueOf(tempC.round());
System.debug('weather1.currentTempC :::'+weather1.currentTempC);
//System.debug('Decimal.valueOf((String)currentWeather.ge;::::' +Decimal.valueOf((String)currentWeather.get('feelslike')));
Decimal feelsLikeF = (Decimal)currentWeather.get('feelslike');
if(feelsLikeF != null){
weather1.feelsLikeF = String.valueOf(feelsLikeF.round()); // feelslike_f
}
Decimal pressure = (Decimal)currentWeather.get('pressure');
weather1.pressure = String.valueOf(pressure.round());
System.debug('weather1.pressure :::'+weather1.pressure);
String isDay = (String)currentWeather.get('is_day');
weather1.isDay = String.valueOf(isDay);
System.debug('weather1.isDay :::'+weather1.isDay);
weather1.weatherIconUrl = (String)currentWeather.get('icon_url'); // icon_url
} else if (untypedMap.containsKey('response') && ((Map<String,Object>)(untypedMap.get('response'))).containsKey('results')) {
System.debug('Entered in elseif');
// do something with search results
} else {
System.debug('Entered in else');
outcomeMsg = 'Error: Verify key not found in response';
}
} else {
// callout failed
outcomeMsg = 'Error: Callout failed. Please review the debug log for additional details.';
}
} catch (DMLexception e) {
// Unexpected exceptions will be caught here, like a deserialization error.
outcomeMsg = 'Error: An exception has been encountered while calling out to Integration: ' + e.getMessage();
}
}
// Return the response
return outcomeMsg;
}
}
Helper class:
({
getLocalWeather: function(component, recID) {
var spinner = component.find('spinner');
$A.util.removeClass(spinner, "slds-hide");
if (recID) {
var action = component.get("c.getLocalWeather");
action.setParams({
"recordId": recID
});
}
action.setCallback(this, function(response) {
this.doLayout(response, component);
});
$A.enqueueAction(action);
},
doLayout: function(response, component) {
var spinner = component.find('spinner');
var data = JSON.parse(response.getReturnValue());
var warning = component.find('warning');
if (data) {
$A.util.addClass(warning, 'slds-hide');
// for testing diff temps
//data['feelsLikeF'] = '900';
component.set("v.weather", data);
console.log("weather data: ", data);
} else {
component.set("v.errorMessage", 'No weather received');
$A.util.removeClass(warning, 'slds-hide');
}
$A.util.addClass(spinner, "slds-hide");
}
})
JS CONTROLLER:
({
doInit: function(component, event, helper) {
var main = component.find('main');
var recID = component.get("v.recordId");
if (recID) {
helper.getLocalWeather(component, recID);
}
},
showDetails: function (component, event, helper) {
var weatherDetails = component.find('weatherDetails');
if (weatherDetails) {
$A.util.toggleClass(weatherDetails, 'slds-hide');
}
}
})
LIGHTNING COMPONENT:
<aura:component controller="WeatherUtil" implements="forceCommunity:availableForAllPageTypes,flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
<aura:attribute name="recordId" type="Id"/>
<aura:attribute name="errorMessage" type="String" />
<aura:attribute name="weather" type="Object"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<div class="slds-box" aura:id="main">
<div aura:id="panelList">
<header>
<h2 class="slds-text-heading--small slds-m-bottom--small">Local Weather</h2>
</header>
</div>
<div style="position:relative;">
<aura:if isTrue="{!v.weather}">
<ul class="slds-list--vertical slds-has-dividers--top-space">
<li class="slds-list__item" onclick="{!c.showDetails}">
<h3 class="slds-text-heading--small slds-m-bottom--x-small">{!v.weather1.displayLocation}</h3>
<p>
<img src="{!v.weather.weatherIconUrl}"/>
{!v.weather1.currentWeather}
</p>
<p>
{!v.weather1.currentTempC}°C<aura:if isTrue="{!v.weather.currentTempF != v.weather.feelsLikeF}">, feels like {!v.weather.feelsLikeF}°F</aura:if>
</p>
<div class="slds-hide" aura:id="weatherDetails">
<ul class="slds-list--vertical">
<li class="slds-list__item">{!v.weather1.currentWind}</li>
<li class="slds-list__item">{!v.weather1.observationTime}</li>
</ul>
</div>
</li>
</ul>
<aura:set attribute="else">
<aura:if isTrue="{!v.errorMessage}">
<p class="slds-hide" aura:id="warning">{!v.errorMessage}</p>
<aura:set attribute="else">
No results found...
</aura:set>
</aura:if>
</aura:set>
</aura:if>
<div class="slds-spinner_container slds-hide" aura:id="spinner">
<div class="slds-spinner--brand slds-spinner slds-spinner--medium" aria-hidden="false" role="alert">
<div class="slds-spinner__dot-a"></div>
<div class="slds-spinner__dot-b"></div>
</div>
</div>
</div>
</div>