how to turn a function into angular scope function - javascript

i've a code like below for calculate distance between two points, this is a code for my ionic project. i used Angularjs-google-maps by allenhwkim, and i want to turn the code into angular scope function so it can run on my View. by the way i get this code from my last question in this forum.
for calculate the distance :
var calcRoute = function(origin,destination,cb) {
var dist;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
var request = {
origin:origin,
destination:destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
cb(null, response.routes[0].legs[0].distance.value / 1000);
}
else {
cb('pass error information');
}
});
};
code below for running the function and hold the result in $scope.A so i can call the result by typing {{A}} on my View
calcRoute("-7.048443, 110.441022","-7.048264, 110.440388", function (err, dist) {
if (!err) {
$scope.A = dist;
}
});
the problem is, i just can use the function inside my controller and send the result with $scope, but how to turn the code for example to {{ calc(ori,dest) }} and return the distance in my View.
i've tried to do like this :
$scope.calc = function(ori,dest){
var calcRoute = function(origin,destination,cb) {
var dist;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
var request = {
origin:origin,
destination:destination,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
cb(null, response.routes[0].legs[0].distance.value / 1000);
}
else {
cb('pass error information');
}
});
};
calcRoute(ori,dest, function (err, dist) {
if (!err) {
return dist;
}else{
console.log("failed");
}
});
return calcRoute();
};
and call the function inside my View like this :
{{calc("-7.048443, 110.441022","-7.048264, 110.440388")}}
it's not working,
return undefined and show console error below :
Error: [$interpolate:interr] Can't interpolate:
{{calc("-7.048443, 110.441022","-7.048264, 110.440388")}}
InvalidValueError: in property origin: not a string; and not a LatLng or LatLngLiteral: not an Object
hope anyone can help me,thanks :))

Not sure you can compute the function on the fly and print the return value.
What you can do is:
Bind your function to a scope function $scope.calc = function(x,y){...}
inside do the usual assignment $scope.A = dist .
In the view just print {{A}}.
To call the function simply use calc(ori,dest). (from your code I didn't get where you should call it).

The error you mentioned is that you are calling calcRoute twice, once with parameters, and once without:
calcRoute(ori,dest, function (err, dist) {
if (!err) {
return dist;
}else{
console.log("failed");
}
});
return calcRoute();
The bigger problem is that you are not going to be able to evaulate your distance this way. Check out this SO post on evaluating asynchronous expressions.
Infinite loop with Angular expression binding
You're going to have to bind your values to $scope. If you're worried about cluttering up your controller with tons of $scope variables you could make an array and add multiple values to it, then use an ng-repeat to display the information in the view.

Related

Google Maps API asynchronous

I'm currently working with the Google Maps API. I use the globalFunction when user click on some button. The "calcRoad" function generate the road by using the Google Maps API, and then "Myfunction" use the data from "calcRoad" to do some calculation.
My problem is that right now "Myfunction" doesn't wait "calcRoad" to end before starting. I asume that some of the Google API requests are asynchronous but I can't access the code behind it.
How could I forced "Myfunction" to wait until "calcRoad" is done ?
function globalFunction(){
calcRoad(true,latitude, longitude);
Myfunction();
}
function calcRoad(bool,lat,long) {
marker.setVisible(false);
var date = new Date();
// Add a waypoint
if(bool){
var tampon = new google.maps.LatLng(lat,long);
waypoints.push({
location: tampon,
stopover:false
});
}
var request = {
origin: departure_place.geometry.location,
destination: arrival_place.geometry.location,
travelMode: google.maps.TravelMode[mode],
waypoints: waypoints,
avoidHighways: false,
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
PS: I tried to use some setTimeout before calling "Myfunction" and it is working but as I don't know how long will the "calcRoad" take to finish (depending on users' parametres) I can't use setTimeout.
I hope that I'm clear with my probleme, thanks in advance for your help.
You should add a callback parameter in your calcRoad function :
function globalFunction(){
calcRoad(true,latitude, longitude, Myfunction);
}
function calcRoad(bool,lat,long, cb) {
marker.setVisible(false);
var date = new Date();
// Add a waypoint
if(bool){
var tampon = new google.maps.LatLng(lat,long);
waypoints.push({
location: tampon,
stopover:false
});
}
var request = {
origin: departure_place.geometry.location,
destination: arrival_place.geometry.location,
travelMode: google.maps.TravelMode[mode],
waypoints: waypoints,
avoidHighways: false,
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
cb && cb(); // Check if "cb" callback function is defined and execute it
}
});
}
Something like this should work !

AngularJS $http running while my other f unction is not finished

I have an AngularJS function case where my $http runs even before my first function is finished
Here is an example format of my code:
$scope.function = function(){
$scope.functionOne(); // This function declares all the scope variable that I need to produce to throw on my API
$scope.functionTwo(); // This is the function that throws a request to my API via $http.post
}
I need those variables but every variable is just a blank string when it reaches to my backend because $http throws a request before the first function finishes
UPDATE
$scope.functionOne = function(){
var geocoder = new google.maps.Geocoder();
if(geocoder){
// console.log("dean")
// console.log($scope.dealership.address);
// console.log($scope.dealership.suburb)
geocoder.geocode({
'address': $scope.dealership.address + ', ' + $scope.dealership.suburb || "1/53 Township Drive, West Burleigh"
}, function(result, status){
// console.log("armada");
// console.log(status);
if(status == google.maps.GeocoderStatus.OK){
console.log(result);
var center_lat = result[0].geometry.location.lat();
var center_lng = result[0].geometry.location.lng();
var lat = result[0].geometry.location.lat();
var lng = result[0].geometry.location.lng();
$scope.$apply();
}
$scope.map.center.latitude = center_lat;
$scope.map.center.longitude = center_lng;
$scope.map.markers.pop();
$scope.map.markers.push({
latitude: lat,
longitude: lng
});
$scope.dealership.latitude = lat;
$scope.dealership.longitude = lng;
$scope.$apply();
});
}
};
$scope.functionTwo = function(){
$scope.loadingData = true;
// The code below is a factory on a scope variable
$scope.dealership.create().then(function(response){
});
}
Promises is the way to go. Once you are done with functionOne resolve the variables and then return the promise. Once the promise is successfully resolved run the second method.
Hope this helps
Happy Learning
Vatsal
The better option for depending function call is to use CallBack function.
Try to call your second function in the callback function of first function.
EDIT:
The another approach of angular is using Promises
You can refer more about it at https://docs.angularjs.org/api/ng/service/$qenter link description here

Remove rendered direction routes on google map

I try to render direction route on google map and my issue was, when I am try to get another direction route previously rendered route not clear. I want to know how I reset rendered route on the map.
Here my code.
function direction(dest, lat, lng) {
$('#direction').slideUp();
$('#results').slideDown();
$('#dest-direction').val(dest);
$('#direction-form').submit(function () {
var ori = $('#origin-direction').val();
map.setZoom(7);
var currentLatLng = new google.maps.LatLng(lat, lng);
map.setCenter(currentLatLng);
var directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
directionsRenderer.setPanel(document.getElementById('direction'));
var directionsService = new google.maps.DirectionsService();
/////////////////////
default_unit_system = google.maps.UnitSystem.METRIC;
if (current_unit == "km") {
default_unit_system = google.maps.UnitSystem.METRIC;
} else if (current_unit == "miles") {
default_unit_system = google.maps.UnitSystem.IMPERIAL;
}
/////////////////////
var request = {
origin: ori,
destination: lat+','+lng,
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: default_unit_system
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(response);
} else {
//alert('Error: ' + status);
$('#direction').append('<table width="100%"><tr><td>Direction not found. Please try again.</td></tr></table>');
}
});
$('#direction-form').nextAll().remove();
return false;
});
}
I agree with Dr.Molle .
Still, One thing that can be useful for many overlays (like markers, like infowindows, ...): Store the objects in an array;
if needed, keep that array on the global scope;
then you can easily remove them from the map.
var renderObjects = [];
function clearRenderObjects() {
for(var i in renderObjects) {
renderObjects[i].setMap(null);
}
}
$('#direction-form').submit(function () {
// clear previous
clearRenderObjects();
...
var directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
// add to the array
renderObjects.push(directionsRenderer);
...
});
Use the same DirectionsRenderer-instance for all requests(currently you create a new instance on each request)

How to wait for Direction Service to complete to access Direction property of Direction Display

I'm doing my work with Google Map API. To draw a route between two points, I use this function:
function calcRoute(start, end) {
var pStart = new google.maps.LatLng(start.lat(), start.lng());
var pEnd = new google.maps.LatLng(end.lat(), end.lng());
var request = {
origin: pStart,
destination: pEnd,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
// Box the overview path of the first route
var path = result.routes[0].overview_path;
boxes = rboxer.box(path, distance);
//drawBoxes(boxes);
nearbyMarkets = search_market(boxes);
// PUT HERE???
}
});
}
After this, I need access the Direction Display object, which only available after the route is rendered successfully (means this function's done). I tried to put that code block in that position, but at that time, the Direction property of Direction Display is still not available, so it's failed. But if I call it after calcRoute function, it's OK.
So, my question is, how can I know when the callback finish so that I can continue my work? I've tried putting a flag like below, but it was unsuccessful, the loop is infinite.
function calcRoute(start, end) {
var pStart = new google.maps.LatLng(start.lat(), start.lng());
var pEnd = new google.maps.LatLng(end.lat(), end.lng());
var pass = false;
var request = {
origin: pStart,
destination: pEnd,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
// Box the overview path of the first route
var path = result.routes[0].overview_path;
boxes = rboxer.box(path, distance);
//drawBoxes(boxes);
nearbyMarkets = search_market(boxes);
pass = true;
}
});
while (!pass) {
}
}
Observe the directions_changed-event:
google.maps.event.addListener(directionsDisplay, 'directions_changed',function(){
if(this.get('directions')){
//directions are available, do something
}
});

JavaScript Objects - Object values getting undefined after constructing

I am trying to create an object that handles Google Maps Api as following:
function GoogleMap(container, mapOptions) {
this.Container = container;
this.Options = mapOptions;
this.Map = new google.maps.Map(document.getElementById(this.Container), this.Options);
// Direction
this.DirectionService = new google.maps.DirectionsService();
this.DirectionRenderer = new google.maps.DirectionsRenderer();
this.DirectionRenderer.setMap(this.Map);
this.DirectionId = 0;
this.DirectionResponse = new Array();
this.DrawDirectionDriving = drawDirectionDriving;
}
and the drawDirectionDriving function is like this:
function drawDirectionDriving(start, end) {
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
this.DirectionService.route(request,
function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
this.DirectionRenderer.setDirections(response);
this.DirectionResponse[this.DirectionId] = response;
this.DirectionId++;
}
else {
alert("Error during drawing direction, Google is not responding...");
}
}
);
}
and in somewhere, I am using the object like this:
var myGoogleMap;
function MapInit() {
myGoogleMap = new GoogleMap("divMap", myMapOptions);
myGoogleMap.DrawDirectionDriving("İstanbul", "Ankara");
}
The Google Map is shown on my browser, there is no problem in constructing the object but error in DrawDirectionDriving function.
When I create a breakpoint on this line: " myGoogleMap.DrawDirectionDriving("İstanbul", "Ankara");" the "DirectionRenderer" seems constructed, but after this line (after the "Draw" method) the DirectionRenderer object seems null (undefined) so it outs en error like this "couldn't get setDirections properties it is null bla bla..."
Could you please give me a hand?
Thanks in advance...
The this keyword does point to something else in the route callback function. It's DirectionRenderer property resolves to null/undefined, and getting the setDirections property from that will cause the exception.
Use a dereferencing variable:
function drawDirectionDriving(start, end) {
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
var that = this;
this.DirectionService.route(request,
function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
that.DirectionRenderer.setDirections(response);
that.DirectionResponse[this.DirectionId] = response;
that.DirectionId++;
// ^^^^ points to the GoogleMap instance
}
else {
alert("Error during drawing direction, Google is not responding...");
}
}
);
}

Categories