javascript behaviour in run time differs from debug - javascript

I have some problem debugging a script, just because in debug mode all works fine... but not in runtime:
I have this function in javascript:
function Add() {
...
$('#Value').val($('#Value').val()); // Value is a div class="input"
...
$.get('#Url.Action("GetSomeData", "_Shared")', { id: parseInt($('#DataID').val()) },
function (result) { $('#SomeData').val(result); });
if ($('#SomeData').val() == "x") {
$('#tmp').val($('#Value').val());
}
else {
$('#tmp').val("0");
}
...
}
and the controller _Shared simply returns an attribute:
public string GetSomeData(int id)
{
return unitOfWork.DataRepository.GetByID(id).Something;
}
What happens is when I use a breakpoint in the "if", $('#SomeData').val() has the correct value but if I remove the breakpoint, write a console.log($('#SomeData').val()) and execute, it is alway empty and the $('#tmp').val() is always "0".
Can anybody tell me what I'm doing wrong?

This is a synchronicity issue. $.get is asynchronous, and the callback you pass it will run when it is finished, not inline with the code where it is written. So your function (result) { $('#SomeData').val(result); }); is running after your if ($('#SomeData').val() == "x") {...
You can fix this by adding the code to run after the $.get to the callback:
$('#Value').val($('#Value').val()); // Value is a div class="input"
...
$.get('#Url.Action("GetSomeData", "_Shared")', { id: parseInt($('#DataID').val()) },
function (result) {
$('#SomeData').val(result);
if ($('#SomeData').val() == "x") {
$('#tmp').val($('#Value').val());
}
else {
$('#tmp').val("0");
}
});
...
Note, it works when you add the breakpoint because that gives your asychronous $.get time to finish and execute.

Did you put the event binding on Jquery on load event?
$(function(){
//Your code here
});
If not, maybe in the runtime, jquery had not found your element (#Value) yet, so it will return empty value.

Ok, I've found a workaround to this asynchronicity situation:
$.get('#Url.Action("GetSomeData", "_Shared")', { id: parseInt($('#DataID').val()) },
function (result) {
if (result == "x") {
$('#tmp').val($('#Value').val());
}
else {
$('#tmp').val("0");
}
$('#SomeData').val(result);
});
Testing inside the function works like a charm. Thanks for the clues.

Related

A js code is working fine from developer tool but not from js file

I can run the following code from my developer console:
jQuery(".skiptranslate").contents().filter(function () {
alert('works again');
return this.nodeType != 1;
}).replaceWith("");
But when I put this same code in js file it has no effect. I put this code in js file inside $(document).ready() function. What's wrong with my code?
You can create a recursive function to check if skiptranslate is ready (rendered/loaded) using $('.skiptranslate').length. If founded run your code if not, wait 100ms then call yourself (do another check), keep check until you found the element.
Use setTimeout to set the delay, my example here is 100ms.
Don't forget to init the function for the first time skiptranslateFn();
My example here simulated the class skiptranslate to be added after 1sec (1000ms).
$(document).ready(function() {
function skiptranslateFn() {
if ($('.skiptranslate').length) {
jQuery(".skiptranslate").contents().filter(function() {
alert('works again');
return this.nodeType != 1;
}).replaceWith("");
console.log('---skiptranslate FOUNDED! ----');
} else {
console.log('skiptranslate not found yet');
setTimeout(function() {
skiptranslateFn()
}, 100);
}
}
//init
skiptranslateFn();
setTimeout(function() {
$('#test').addClass('skiptranslate');
console.log('element loaded!');
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
test div
</div>

How can I tell all Angular commands are complete from Javascript?

I am using the following to detect when my page has finished loading, but it is evidently wrong. The Angular stuff has not been executed yet when document.readyState is complete:
page.open(url, function (status) {
function checkReadyState() {
setTimeout(function () {
var readyState = page.evaluate(function () {
return document.readyState;
});
if ("complete" === readyState) {
// onPageReady();
doRender();
} else {
checkReadyState();
}
});
}
checkReadyState();
});
I didn't get the purpose exactly but you can use $timeout inside angular code which gets executed only after all execution is finished for that particular angular page, and pass a global method which is defined inside your javascript code.
Something like this-
Inside JS file -
var callBack = function(){
console.log('I have finished execution');
}
Inside Angular Controller -
$timeout(function(){
callBack();
});
If it doesn't solve your problem please elaborate more.

How to know if document has loaded

I have a piece of JS code which needs to determine if DOM has loaded. I know there are several ways of executing JS code when DOM has loaded like:
$(document).ready(function() { ... }); // Jquery version
document.body.onload = function() { ... } // Vanila JS way
I am looking for some method which looks like
function isDOMLoaded() {
// Do something to check if DOM is loaded or not
// return true/false depending upon logic
}
PS: Update (Post Answer Accept)
I happen to see jquery also use the same approach to check if DOM has loaded. Take a look at the Implementation of jquery.ready() here
bindReady: function() {
if ( readyBound ) {
return;
}
readyBound = true;
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
return jQuery.ready();
}
...
function isDOMLoaded(){
return document.readyState == 'complete';
}
You can use something like this
function isLoaded() {
return (document.readyState === 'ready' ||
document.readyState === 'complete')
}
Check for ready and complete status.
ready is only there for a short moment but do reflect when the DOM is ready. When the page is completely loaded however the status is changed to 'complete'. If you happen to check only for ready the function will fail, so we also check for this status.
How about this?
var flgDOMLoaded=false; //Set a global variable
$(document).ready(function() {
flgDOMLoaded= true;
// Some code
});
function isDOMLoaded() {
return flgDOMLoaded; // return it.
//You don't need this function at all. You could just access window.flgDOMLoaded
}

javascript does not reconnect to server side if connection is lost

I have Jquery+Ajax page that connects to server gets some data, and displays it. This is done all the time, function calls itself after it completes all task and starts to perform again and again. But If komputer loses internet connection everything stops. And when connections comes back again, nothing happens. Here is javascript code. How can I iprove it so it will continue to work after connection is back again.
$(document).ready(function() {
var a=1;
var max='23';
function kiosk()
{
if(a<max)
{
$.post('engine.php', { index: a },
function(result)
{
result = jQuery.parseJSON(result);
$('#main').css({'display':'none'});
$('#div_city').html(result.dest);
$('#div_price').html(result.price);
$('#div_price_pre').html('From ');
$('#div_price_after').html(' Euro');
$('#main').fadeIn(2000).delay(3000).fadeOut(2000, function()
{
$('#main').hide;
a++;
kiosk();
});
});
}
else
{
a=1;
kiosk();
}
}
kiosk();
});
I would suggest rather than using $.post you use
$.ajax({ type: "post" , success : function1() , failure: function2() }.
In function2() you can call koisk again after a timeout. and the succces would be the function you have created right now.
This link will help you understand the ajax function jQuery Ajax error handling, show custom exception messages
Eg Code snippet:
function kiosk()
{
if(a<max)
{
$.ajax({type : "POST" , url : 'engine.php',data: { index: a },
success : function(result)
{
result = jQuery.parseJSON(result);
$('#main').css({'display':'none'});
$('#div_city').html(result.dest);
$('#div_price').html(result.price);
$('#div_price_pre').html('From ');
$('#div_price_after').html(' Euro');
$('#main').fadeIn(2000).delay(3000).fadeOut(2000, function()
{
$('#main').hide;
a++;
kiosk();
});
},error : function (xhr, ajaxOptions, thrownError){ setTimeout(200,kiosk()) }
});
}
else
{
a=1;
kiosk();
}
}
kiosk();
});`
Using jQuery.post you are passing a callback which is executed only on success.
You should use jQuery.ajax which has different callbacks. See documentation with complete, success and error callbacks.
You could even use statusCode to map a specific HTTP code to a custom function.
Script brokes because i think it throws exception. You can add your code try and catch block, and even if has errors you can continue to try.
try {
result = jQuery.parseJSON(result);
// do your work
} catch {
// call function again
}
Or you can use, jquery ajax, it has a onerror event.

weird problem - change event fires only under debug in IE

I have form autocomplete code that executes when value changes in one textbox. It looks like this:
$('#myTextBoxId)').change(function () {
var caller = $(this);
var ajaxurl = '#Url.Action("Autocomplete", "Ajax")';
var postData = { myvalue: $(caller).val() }
executeAfterCurrentAjax(function () {
//alert("executing after ajax");
if ($(caller).valid()) {
//alert("field is valid");
$.ajax({ type: 'POST',
url: ajaxurl,
data: postData,
success: function (data) {
//some code that handles ajax call result to update form
}
});
}
});
});
As this form field (myTextBoxId) has remote validator, I have made this function:
function executeAfterCurrentAjax(callback) {
if (ajaxCounter > 0) {
setTimeout(function () { executeAfterCurrentAjax(callback); }, 100);
}
else {
callback();
}
}
This function enables me to execute this autocomplete call after remote validation has ended, resulting in autocomplete only when textbox has valid value. ajaxCounter variable is global, and its value is set in global ajax events:
$(document).ajaxStart(function () {
ajaxCounter++;
});
$(document).ajaxComplete(function () {
ajaxCounter--;
if (ajaxCounter <= 0) {
ajaxCounter = 0;
}
});
My problem is in IE (9), and it occurs only when I normally use my form. Problem is that function body inside executeAfterCurrentAjax(function () {...}); sometimes does not execute for some reason. If I uncomment any of two alerts, everything works every time, but if not, ajax call is most of the time not made (I checked this by debugging on server). If I open developer tools and try to capture network or debug javascript everything works as it should.
It seems that problem occurs when field loses focus in the same moment when remote validation request is complete. What I think it happens then is callback function in executeAfterCurrentAjaxCall is executed immediately, and in that moment jquery validation response is not finished yet, so $(caller).valid() returns false. I still do not know how alert("field is valid") helps in that scenario, and that could be sign that I'm wrong and something else is happening. However, changing executeAfterCurrentAjaxCall so it looks like this seems to solve my problem:
function executeAfterCurrentAjax(callback) {
if (ajaxCounter > 0) {
setTimeout(function () { executeAfterCurrentAjax(callback); }, 100);
}
else {
setTimeout(callback, 10);
}
}

Categories

Resources