ReferenceError: function not defined - javascript

I am trying to invoke a javascript method. I am building the html at run time by string concatenation.
$scope.getRoute = function (isRouteFormValid) {
routingDemoPageService.executeService(serviceURL, 'admin', 'admin').then(function (response) {
function tryingOnceAgain() {
alert('called.....');
}
var markers = L.markerClusterGroup({
showCoverageOnHover:false,
chunkedLoading: true
});
var geojsonLayer = L.geoJson(response, {
onEachFeature: function(feature, layer){
var UIDValue = (feature.properties['uid'] !== null ? Autolinker.link(String(feature.properties['uid'])) : '');
var popupContent = '<table>' +
'<tr><th scope="row">Edit</th><td></td></tr>' +
'<tr><th scope="row">uid</th><td>' + UIDValue + '</td></tr></table>';
layer.bindPopup(popupContent);
}
});
markers.addLayer(geojsonLayer);
$scope.map.addLayer(markers);
$scope.map.fitBounds(markers.getBounds());
})['catch'](function (error) {
});
}
When i click on the link, which invokes tryingOnceAgain method, i am getting following error
ReferenceError: tryingOnceAgain is not defined
I am not sure why i am getting following error.
Can someone please provide any pointers what am i doing wrong.

javascript:tryingOnceAgain() is referenced to a function in the global scope but you defined tryingOnceAgain function inside function (response) { scope.
To fix that you have to move your tryingOnceAgain function to global scope.
Or just assign it to window object without changing physical place:
window.tryingOnceAgain = function() {...}

Your function-definition for tryingOnceAgain() exists only inside the function where it is defined, in this case $scope.getRoute().
This makes that only code inside $scope.getRoute() can call tryingOnceAgain() and it'll run.
You'll have to define tryingOnceAgain() outside of $scope.getRoute() or make it a public property and call it like that inside the HTML.

Related

Questions related to JavaScript object literal and google map API

This code is not working as expected. I am trying to use the Google Geolocation API to figure out my current location. However, when I try to log the result for the google.maps.LatLng object, I got (0,0) as the latitude and longitude coordinates.
$(document).ready(function(){
var func = {
lat:0,
long:0,
success:function(pos) {
var crd = pos.coords;
this.lat = crd.latitude;
this.long = crd.longitude;
},
error:function(err) {
console.log('ERROR(' + err.code + '): ' + err.message);
},
init:function(){
navigator.geolocation.getCurrentPosition(this.success, this.error);
}
};
func.init();
$('button').on('click',function(){
var loc = new google.maps.LatLng(func.lat, func.long);
alert(loc);
});
});
However, the code underneath works. All I did was changing "this" keyword to the object's name. It shouldn't make a difference.
$(document).ready(function(){
var func = {
lat:0,
long:0,
success:function(pos) {
var crd = pos.coords;
func.lat = crd.latitude;
func.long = crd.longitude;
},
error:function(err) {
console.log('ERROR(' + err.code + '): ' + err.message);
},
init:function(){
navigator.geolocation.getCurrentPosition(func.success, func.error);
}
};
func.init();
$('button').on('click',function(){
var loc = new google.maps.LatLng(func.lat, func.long);
alert(loc);
});
});
I am not sure why the code snippet on the top produces incorrect output? I am not too familiar with Objected Oriented JavaScript. I would appreciate it if anyone could help me understand what is going on.
In your first example, when you call:
getCurrentPosition(this.success, this.error);
You are merely passing the success and error functions into getCurrentPosition. Even though you reference them here via this, that is not carried through to the point where the functions are actually called. It only passes the function references themselves, not the this value that you were using here.
Another way to understand the problem: the value of this inside a function is determined at the time the function is called. When you write foo.bar() you are calling the bar() function with foo as the this value inside the function. But when you write foo.bar without the (), you are only getting a reference to bar itself. foo is out of the picture after that. If you pass foo.bar into another function which expects a callback, when it finally calls bar() there is no longer any association with foo.
That's why your second example works. It does not depend on this but uses func which is valid throughout the outer function.

JavaScript " is not a function" error when passing function as argument

I have this piece of code in html header:
<script src="../scripts/scripts.js"></script>
<script>
$(document).ready(function() {
window.LastConnection=null;
AjaXUpdateDetails(SetDetailsToHtmlPage);
});
</script>
in scripts.js I have:
var SetDetailsToHtmlPage=function (details_array){
window.LastConnection;
if (window.LastConnection!==null) {
if (window.LastConnection!==details_array.last_connection) {
$("#EStatus").val(details_array.status);
}
}
};
and
function AjaXUpdateDetails(interfaceUpdateFunc){
var ajaxRequest;
if ( (ajaxRequest=getAjaxObject())===false ) return;
ajaxRequest.onreadystatechange = function() {
if(ajaxRequest.readyState == 4) {
var data_array =jQuery.parseJSON(ajaxRequest.responseText);
interfaceUpdateFunc(data_array);
}
};
var queryString = "?id=1";
ajaxRequest.open("GET", "../scripts/AjaXgetDetails.php" + queryString, true);
ajaxRequest.send(null);
}
I read a lot about passing functions as arguments and thought I understood the idea but I keep getting error:
TypeError: interfaceUpdateFunc is not a function
interfaceUpdateFunc(data_array);
Where do I make a mistake?
thanks and regards
Tom
Try checking it before you pass it to AjaXUpdateDetails:
$(document).ready(function() {
window.LastConnection=null;
// verify it is defined here
console.log(SetDetailsToHtmlPage, typeof SetDetailsToHtmlPage)
AjaXUpdateDetails(SetDetailsToHtmlPage);
});
I suspect that will tell you the function is undefined at this point (scope issue). You can probably fix it by changing:
var SetDetailsToHtmlPage=function (details_array) {
to
function SetDetailsToHtmlPage(details_array) {
Here are couple of investigative changes that you can try:
1) The Function expression var SetDetailsToHtmlPage=function (details_array) is not in a function so it has global scope. Because it is an expression then the variable will be "hoisted" which means it is declared before it is assigned to the function. So try declaring it as a function: function SetDetailsToHtmlPage(details_array). This will cause the function declaration including the function to get "hoisted" in the same scope as the document ready event.
2) If that has no effect then try using jQuery document event .load() as opposed to .ready() to see if that has an effect.
$(document).load(function() {
window.LastConnection=null;
AjaXUpdateDetails(SetDetailsToHtmlPage);
});
interfaceUpdateFunc is a param. You could not call by that way.
if (typeof(interfaceUpdateFunc) == "function") {
interfaceUpdateFunc.apply(this, [data_array]);
}
You can check object is a function by this way:
function isFunction(func) {
return Object.prototype.toString.call(func) == '[object Function]';
}
And
if (isFunction(interfaceUpdateFunc)) {
interfaceUpdateFunc.apply(this, [data_array]);
}

Passing a variable from a callback function to another function?

I am working on setting up an HTML5 GeoLocation script and I would like to store the zip code in a cookie but for now I am just trying to figure out how to pass the zip code variable into another function.
Here is my script to reverse geo-code based on lat/long:
function retrieve_zip(callback)
{
try { if(!google) { google = 0; } } catch(err) { google = 0; } // Stupid Exceptions
if(navigator.geolocation) // FireFox/HTML5 GeoLocation
{
navigator.geolocation.getCurrentPosition(function(position)
{
zip_from_latlng(position.coords.latitude,position.coords.longitude,callback);
});
}
else if(google && google.gears) // Google Gears GeoLocation
{
var geloc = google.gears.factory.create('beta.geolocation');
geloc.getPermission();
geloc.getCurrentPosition(function(position)
{
zip_from_latlng(position.latitude,position.longitude,callback);
},function(err){});
}
}
function zip_from_latlng(latitude,longitude,callback)
{
// Setup the Script using Geonames.org's WebService
var script = document.createElement("script");
script.src = "http://ws.geonames.org/findNearbyPostalCodesJSON?lat=" + latitude + "&lng=" + longitude + "&callback=" + callback;
console.log(script.src);
// Run the Script
document.getElementsByTagName("head")[0].appendChild(script);
}
function callback(json)
{
zip = json.postalCodes[0].postalCode;
country = json.postalCodes[0].countryCode;
state = json.postalCodes[0].adminName1;
county = json.postalCodes[0].adminName2;
place = json.postalCodes[0].placeName;
alert(zip);
}
$('#findLocation').click(function(event) {
event.preventDefault();
console.log(zip); // This is giving me undefined currently
});
So basically, in the callback function, I want to store the zip code as a variable(rather than displaying it in an alert) and then in the on click function at the bottom, I want to be able to display the zip code that was stored in the previous callback function.
Any help greatly appreciated, still pretty new to Javscript/jQuery, thanks!
You could set zip as a 'global' variable by including it outside of the function at the top of the document like so:
var zip;
...
Alternatively, you may consider defining an object at the 'global' level and using it as a namespace to store variables like so:
window.address = {};
function callback(json){
address.zip = json.postalCodes[0].postalCode;
address.country = json.postalCodes[0].countryCode;
address.state = json.postalCodes[0].adminName1;
address.county = json.postalCodes[0].adminName2;
address.place = json.postalCodes[0].placeName;
}
$('#findLocation').click(function(event) {
event.preventDefault();
console.log(address.address);
console.log(address.zip);
...
});
I hope this helps!
Define var zip at very begining of code. You haven't defined it.
I haven't tried, but it should solve your problem.
Also, it seems that you forgot to define other variables in callback function as well.
What I would do, is to avoid the anonymous function in the event handler, that is, create a new named function -which gives you the added benefit of traceability during debugging- and then use that function as the event handler callback:
function eventHandlerFunction(event) {
var zip;
event.preventDefault();
zip = eventHandlerFunction.zip;
console.log(zip);
}
function callback(json) {
var zip;
zip = doSomethingWithJsonToGetTheZip();
eventHandlerFunction.zip = zip;
}
$("#findLocation").click(eventHandlerFunction);
Or, better yet, code this as a module and then you have member encapsulation and you can share variables amongst functions without modifying the global object. You never know when another library will modify the same global member that you are using.
var yourModule = (function($) {
var zip;
function retrieveZip(callback) {
// your code
}
function callback(json) {
// do something with json
zip = json.zip; // or whatever
}
$("#findLocation").click(function(event) {
event.preventDefault();
console.log(zip); // zip is visible in the parent scope + this scope
});
}(jQuery));

My javascript function cannot be found

I have the following:
$(function () {
$.ajaxSetup({ cache: false });
var dialogs = {};
var formSubmitHandler = function (e) {
...
}
}
then in another script I try to call
function dialogClick(link) {
$.get(viewUrl + parameters)
.success(function (content) {
if (content.match(/^[eE]rror/)) {
mvcOnFailure(data)
} else {
$.modal({
title: title,
closeButton: true,
content: content,
width: false,
resizeOnLoad: true
}).find('form').submit(formSubmitHandler).end();
}
})
Note that I have cut out parts of the script to make it easy to read. There are no script errors showing just the following error:
In the second script I get an error message saying "SCRIPT5009: 'formSubmitHandler' is undefined' in Internet Explorer.
Am I calling it wrongly? I thought the function would be global and when I check
the script that it is inside of is attached to the page.
No, it's not global; your "formSubmitHandler" function is declared within the "ready" callback in the first block of sample code you posted. It's therefore private to that function.
What you could do, if you really want a global function, is:
window['formSubmitHandler'] = formSubmitHandler;
in the first function. Or, alternatively, you could make it a jQuery "global" function:
$['formSubmitHandler'] = formSubmitHandler;
In that case, you'd get to it as $.formSubmitHandler.
Try moving your function out of the function block e.g
$(function () {
$.ajaxSetup({ cache: false });
var dialogs = {};
}
var formSubmitHandler = function (e) {
...
}
formSubmitHandler only exists within the function scope you declare it, since you used the var variable.
You need to either:
declare dialogClick in the same scope
declare formSubmitHandler in the global scope, using window.formSubmitHandler or simply function formSubmitHandler(){}
formSubmitHandler is a function declared in a scope not visible for the dialogClick() function
So
Either you declare formSubmitHandler as global
or you define the function dialogClick inside document.ready function (and formSubmitHandler is reachable since is in a parent scope)

Class and attribute problem

I wanted to play with geolocation API on my Android. I know that there is a "navigator" object that is defined and that should be used to aquire user position. So, I created this sample code:
function GeolocationTester()
{
// here I want to store all acquired locations
this.locations = new Array();
alert("this.locations defined: " + this.locations);
this.onSuccess = function(position)
{
alert("Entered onSuccess");
alert("this.locations defined: " + this.locations);
}
this.onError = function(error)
{
alert("error acquiring location");
}
navigator.geolocation.watchPosition(this.onSuccess, this.onError, { enableHighAccuracy: true });
}
And it doesn't work for me. Each time watchPosition call onSuccess the this.locations field isn't defined (and it is defined just after new Array). I known that I'm doing somethind wrong, but as it is one of my JavaScript attempts, not sure what. So, anybody could find a problem here?
The problem is with the scoping of this. When the onSuccess or onError is called, this isn't bound to the object containing the locations array. You need to create an explicit variable outside of the functions to which the array should be assigned and then use this variable in the callbacks, like this:
var allLocations = this.locations = [a, b, c];
this.onSuccess = function(position) {
alert("allLocations: " + allLocations);
alert("this.locations: " + this.locations);
}
Its cause you using this. This will change cause its depends on the context your function is calling on. Just use the scope of the function to declare location:
function GeolocationTester()
{
// here I want to store all acquired locations
var locations = [];
alert("locations defined: " + locations);
function onSuccess(position) {
alert("Entered onSuccess");
alert("locations defined: " + locations);
}
function onError(error){
alert("error acquiring location");
}
navigator.geolocation.watchPosition(onSuccess, onError, { enableHighAccuracy: true });
}
To really understand what this read this blog post http://dmitrysoshnikov.com/ecmascript/chapter-3-this/
Try to define onSuccess like this:
this.onSuccess = (function(locations) {
return function(position)
{
alert("Entered onSuccess");
alert("this.locations defined: " + locations);
}
})(this.locations);

Categories

Resources