function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ravi Dutt SharmaRavi Dutt Sharma 

setCallBack between 2 functions present in JS Helper

I have 2 functions in my JS helper - getLatLng and getResponse. getLatLng gets the current location of the user and sets two attributes in the component namely lat and lng. getResponse uses these two attributes for further processing. I am calling both these functions from my JS controller one after the other. The problem is that getResponse gets called even before the execution of getLatLng is completed. Is there any way to set a callback so that when getLatLng sets the lat and lng on component, then only getResponse is called? Here is the code for JS controller and  JS helper.

WeatherController.js
 
({
    doInit : function(component, event, helper) {
        helper.getLatLng(component);
        helper.getResponse(component);
    }
})
WeatherHelper.js
({
    getResponse : function(component){
        var action = component.get("c.getCalloutResponseContents");
        var lat = component.get("v.lat");
        var lng = component.get("v.lng");
        action.setParams({
            "url": 'http://api.openweathermap.org/data/2.5/weather?lat=' +lat+ '&lon=' +lng+ '&appid=9b2719bd93477d05ad2575ccb81cb666&units=metric'
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.response", JSON.parse(response.getReturnValue()));
            }
        });
        $A.enqueueAction(action);
    },
    
    getLatLng : function(component) {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                component.set("v.lat", position.coords.latitude);
                component.set("v.lng", position.coords.longitude);
            });
        } 
    }
    
})
Thanks in advance for your help.
Best Answer chosen by Ravi Dutt Sharma
sfdcMonkey.comsfdcMonkey.com
hi ravi
i update your code try below code
WeatherHelper.js
 
({
    getResponse : function(component,event){
        var action = component.get("c.getCalloutResponseContents");
        var lat = event.getParam("lat"); // ### no need to use v. here
        var lng = event.getParam("lng"); // ### no need to use v. here
        console.log('lat: '+lat);
        console.log('lng: '+lng);
        action.setParams({
            "url": 'http://api.openweathermap.org/data/2.5/weather?lat=' +lat+ '&lon=' +lng+ '&appid=9b2719bd93477d05ad2575ccb81cb666&units=metric'
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.response", JSON.parse(response.getReturnValue()));
            }
        });
        $A.enqueueAction(action);
    }
    
})

LatLngHelper.js

we fire the event when the response is come back from server for
navigator.geolocation.getCurrentPosition
 
({
    getLatLng : function(component,event,helper) {
        var lat,lng;
        
        if (navigator.geolocation) {
            console.log('Geolocation is supported');
            navigator.geolocation.getCurrentPosition(function(position) {
                lat =  position.coords.latitude;
                lng = position.coords.longitude;
           // now fire the event 
       var latLngEvent = $A.get("e.c:latLngEvent");
      latLngEvent.setParams({
             "lat": lat,
             "lng": lng
	   });
	latLngEvent.fire();             
 
            });
        }   
    },
})
output -:
User-added image
thanks let me inform if it helps you :)
sfdcmonkey.com


 

All Answers

Ravi Dutt SharmaRavi Dutt Sharma
Hi Piyush,

Thanks for your reply. I am trying to optimize the code a bit and have broken down Weather component into two components.

Weather.cmp
 
<aura:component controller="WeatherCtrl">
    
    <aura:handler event="c:latLngEvent" action="{!c.getWeatherDetails}"/>
    
    <aura:attribute name="response" type="WeatherResponse"/>

</aura:component>

WeatherController.js
 
({
    getWeatherDetails : function(component, event, helper) {
        console.log('Inside WeatherController');
        helper.getResponse(component,event);
    }
})
WeatherHelper.js
 
({
    getResponse : function(component,event){
        var action = component.get("c.getCalloutResponseContents");
        var lat = event.getParam("v.lat");
        var lng = event.getParam("v.lng");
        console.log('lat: '+lat);
        action.setParams({
            "url": 'http://api.openweathermap.org/data/2.5/weather?lat=' +lat+ '&lon=' +lng+ '&appid=9b2719bd93477d05ad2575ccb81cb666&units=metric'
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.response", JSON.parse(response.getReturnValue()));
            }
        });
        $A.enqueueAction(action);
    }
    
})

LatLng.cmp
 
<aura:component>
	
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
    <aura:registerEvent name="latLngEvent" type="c:latLngEvent"/>
    
    <c:Weather />
</aura:component>

LatLngController.js
 
({
	doInit : function(component, event, helper) {
		helper.getLatLng(component,event,helper);
	}
})

LatLngHelper.js
 
({
    getLatLng : function(component,event,helper) {
        var lat,lng;
        
        if (navigator.geolocation) {
            console.log('Geolocation is supported');
            navigator.geolocation.getCurrentPosition(function(position) {
                lat =  position.coords.latitude;
                lng = position.coords.longitude;
                helper.fireEvent(component, event, lat, lng);
            });
        } 
        
        
    },
    
    fireEvent : function(component, event, lat, lng){
    
    var latLngEvent = $A.get("e.c:latLngEvent");
    latLngEvent.setParams({
        "lat": lat,
        "lng": lng
	});
	latLngEvent.fire();
	}

})

latLngEvent.evt
 
<aura:event type="APPLICATION" access="global">
    <aura:attribute name="lat" type="Decimal"/>
    <aura:attribute name="lng" type="Decimal"/>
</aura:event>

WeatherApp.app
 
<aura:application extends="force:slds">
    <c:LatLng />
</aura:application>

The issue that I am facing now is in WeatherHelper.js, the console.log is printing the value of lat as undefined. Any idea why the value is not coming? Thanks for your help.






 
Ravi Dutt SharmaRavi Dutt Sharma
Also, please note that in LatLngHelper.js, there is an async call to get the lat, lng of current user. I think because of the async call, the lat and lng are coming as null. Any way to wait until the async call completes its execution?
sfdcMonkey.comsfdcMonkey.com
hi buddy
yes i find this issue its heppen because lightning is  async freamwork so its not wait for complete the navigator.geolocation.getCurrentPosition function so you getting null value, anyway i find any other way for do it and i post here ASAP
thanks
sfdcMonkey.comsfdcMonkey.com
hi ravi
i update your code try below code
WeatherHelper.js
 
({
    getResponse : function(component,event){
        var action = component.get("c.getCalloutResponseContents");
        var lat = event.getParam("lat"); // ### no need to use v. here
        var lng = event.getParam("lng"); // ### no need to use v. here
        console.log('lat: '+lat);
        console.log('lng: '+lng);
        action.setParams({
            "url": 'http://api.openweathermap.org/data/2.5/weather?lat=' +lat+ '&lon=' +lng+ '&appid=9b2719bd93477d05ad2575ccb81cb666&units=metric'
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.response", JSON.parse(response.getReturnValue()));
            }
        });
        $A.enqueueAction(action);
    }
    
})

LatLngHelper.js

we fire the event when the response is come back from server for
navigator.geolocation.getCurrentPosition
 
({
    getLatLng : function(component,event,helper) {
        var lat,lng;
        
        if (navigator.geolocation) {
            console.log('Geolocation is supported');
            navigator.geolocation.getCurrentPosition(function(position) {
                lat =  position.coords.latitude;
                lng = position.coords.longitude;
           // now fire the event 
       var latLngEvent = $A.get("e.c:latLngEvent");
      latLngEvent.setParams({
             "lat": lat,
             "lng": lng
	   });
	latLngEvent.fire();             
 
            });
        }   
    },
})
output -:
User-added image
thanks let me inform if it helps you :)
sfdcmonkey.com


 
This was selected as the best answer
Ravi Dutt SharmaRavi Dutt Sharma
Hi Piyush,

You are a champ. I changed the way I was fetching parameters from components (changed v.lat to lat as suggested by you) and its working now. Thanks a lot.