The following code I am running and during execution I receive an error.
public void GetCategoriesSelenium() {
string javascript = System.IO.File.ReadAllText(#"GetCategory.js");
CrawlerWebSeleniumJS.ExecuteScript("var finished;");
CrawlerWebSeleniumJS.ExecuteScript("var all_categories;");
CrawlerWebSeleniumJS.ExecuteScript("finished = false;");
CrawlerWebSeleniumJS.ExecuteScript("all_categories = [];");
CrawlerWebSelenium.Manage().Timeouts().SetScriptTimeout(TimeSpan.FromDays(1));
CrawlerWebSelenium.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromDays(1));
CrawlerWebSelenium.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromDays(1));
AddToConsole("CRAWLER: GET - Categories");
try {
CrawlerWebSeleniumJS.ExecuteScript(javascript);
}
catch {
}
int ready = 2;
for (int i = 0; i < ready; i++) {
try {
if (CrawlerWebSeleniumJS.ExecuteScript("return finished").ToString() == "True") {
i = i++ + ready++;
}
else {
ready++;
}
}
catch {
}
}
AddToCatsTreeSelenium();
}
$('.p-pstctgry-lnk-ctgry').each(function (i) {
var idBits = this.id.split('_');
var theId = idBits[1];
var theTitle = this.text;
var subcategories = [];
//initiate ajax request for json results
$.ajax({
async: false,
type: 'GET',
dataType: 'json',
url: 'URL REMOVED',
data: {
nodeType: 'cat',
level1id: theId
}
}).done(function (theJSON1) {
var thelength1 = Object.keys(theJSON1['items']).length;
//loop through found subs
for (var i = 0; i < thelength1; i++) {
//start of next recursive block to copy and paste inside
var subsubcategories = [];
//initiate ajax request for sub json results
$.ajax({
async: false,
type: 'GET',
dataType: 'json',
url: 'URL REMOVED',
data: {
nodeType: 'cat',
level1id: theId,
level2id: theJSON1['items'][i]['id']
}
}).done(function (theJSON2) {
var thelength2 = Object.keys(theJSON2['items']).length;
for (var k = 0; k < thelength2; k++) {
//start of next recursive block to copy and paste inside
var subsubsubcategories = [];
//initiate ajax request for sub json results
if ((theJSON2['items'][k]['id'] != 'OFFER') && (theJSON2['items'][k]['id'] != 'WANTED')) {
$.ajax({
async: false,
type: 'GET',
dataType: 'json',
url: 'URL REMOVED',
data: {
nodeType: 'cat',
level1id: theId,
level2id: theJSON1['items'][i]['id'],
level3id: theJSON2['items'][k]['id']
}
}).done(function (theJSON3) {
var thelength3 = Object.keys(theJSON3['items']).length;
for (var l = 0; l < thelength3; l++) {
console.log('---' + theJSON3['items'][l]['value'] + ' ' + theJSON3['items'][l]['id']);
//store this subsub
subsubsubcategories.push({
title: theJSON3['items'][l]['value'],
id: theJSON3['items'][l]['id'],
sub: ''
});
}
//end done theJSON
});
}
//end of next recursive block to copy and paste inside
console.log('--' + theJSON2['items'][k]['value'] + ' ' + theJSON2['items'][k]['id']);
//store this subsub
subsubcategories.push({
title: theJSON2['items'][k]['value'],
id: theJSON2['items'][k]['id'],
sub: subsubsubcategories
});
}
//end done theJSON
});
console.log('-' + theJSON1['items'][i]['value'] + ' ' + theJSON1['items'][i]['id']);
//store this sub with -> subsub
subcategories.push({
title: theJSON1['items'][i]['value'],
id: theJSON1['items'][i]['id'],
sub: subsubcategories
});
//end of next recursive block to copy and paste inside
//end sub loop
}
console.log('' + theTitle + ' ' + theId);
//store this cat with -> sub -> subsub
all_categories.push({
title: theTitle,
id: theId,
sub: subcategories
});
console.log(all_categories);
//end first json subcat loop
});
//end main cat scan loop
});
finished = true;
The above code is the method that I run and the code that is under it is pure javascript that is being run through selenium.
So issue one, when the code is run selenium locks up. Which I can understand. This process takes about 4mins. After 60secs it times out with the error
The HTTP request to the remote WebDriver server for URL timed out after 60 seconds.
Which is really annoying and locks the system up. I know a really quick and easy way to get this fixed. (Thread.Sleep(300000) which is disgusting...
My thoughts are, maybe it is running a javascript query and waiting for it to finish and I am constantly pounding Selenium with more javascript requests which time out as expected.
Any other thoughts?
The driver's constructor should have an overload that includes a TimeSpan indicating the timeout for the HTTP client used by the .NET bindings to communicate with the remote end. Setting that to an appropriately large value should be sufficient to let the operation complete.
Related
I am setting items to localstorage using the below code. The issue I am getting is whenever I refresh the page some of the items are not set when I inspect the localstorage it shows as undefined, this is absolutely random and sometimes all items are set parfectly. How can I ensure that all the items are set without any undefined?
const catdata = [];
var catArr = JSON.parse(localStorage.getItem('cat'));
for (let i = 0; i < catArr.length; i++) {
const catid = catArr[i]['id'];
const catname = catArr[i]['name'];
$('#topitems').prepend('<div ><a class="topitems" href="'+catArr[i]['id']+'">'+catArr[i]['name']+'</a></div>');
(function(i) {
$.ajax( { url : "sales/item_search_cat?cat="+catid
, data : "GET"
// , async: "false",
, dataType : "json"
, success : function(data) {
catdata.push(data);
localStorage.setItem(catid,JSON.stringify(catdata[i]));
}
});
})(i);
}
The execution of the ajax requests are not sequentially executed, and sometimes your code is accessing an index that doesn't exist.
For example, one response arrives with index 2, the code pushes into the empty array at index 0, and catdata[i] is trying to get the index 2.
I think you have to call the ajax request using await or you can use the data directly:
localStorage.setItem(catid, JSON.stringify(data));
Possible solution (I didn't test it):
The execution is async, if you need to wait for the executions, you have to follow an async/await approach.
function callAjax(catid) {
$.ajax({
url: "sales/item_search_cat?cat=" + catid,
data: "GET",
dataType: "json",
success: function(data) {
localStorage.setItem(catid, JSON.stringify(data));
success(data);
}
});
}
let catArr = JSON.parse(localStorage.getItem('cat'));
catArr.forEach(function({id: catid, name: catname}) {
$('#topitems').prepend('<div ><a class="topitems" href="' + catid + '">' + catname + '</a></div>');
callAjax(catid);
});
So, this is the code I have, console.log gives me the right value, but the function doesn't return the value, even if the return is inside the timeout. I must be doing something wrong.
function countyfinder(address){
var rr =$.getJSON('https://maps.googleapis.com/maps/api/geocode/json?address=' + address.replace(" ", "%20")).done(function(data) {
var county = data.results[0].address_components[3].short_name;
//return county;//data is the JSON string
});return rr;};
function calculatetax(address, price){
var j = countyfinder(address);
setTimeout(function(){var k = j["responseJSON"]['results'][0]['address_components'][3]['short_name'];
console.log(k);//return k won't work in here either
}, 1000); return k
};
this is what I ended up with:
var jq = document.createElement('script');
jq.src = "//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
function getCounty(address) {
var country;
var baseApiUrl = "https://maps.googleapis.com/maps/api/geocode/json";
var query = "?address=" + encodeURIComponent(address);
var queryUrl = baseApiUrl + query;
$.ajax({
url: queryUrl,
async: false,
dataType: 'json',
success: function(data) {
county = gmapsExtractByType(data, "administrative_area_level_2 political");
}
});
return countr.long_name;
}
function gmapsExtractByType(json, type) {
return json.results[0].address_components.filter(function(element) {
return element.types.join(" ") === type;
})[0];
}
console.log( getCounty("100 wacko lane ohio") );
I had to use a synchronous request by changing some settings in the ajax request. The drawback of this is that the browser will be locked up until you get a request response, which can be bad on a slow connection or a connection with an unreliable server. With google, most of the time, I don't think that will happen.
I am new in Famo.us framework. i have small Application in Famo.us framework.
I have following Code:
define(function (require, exports, module) {
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var View = require('famous/core/View');
var HeaderFooterLayout = require('famous/views/HeaderFooterLayout');
var App = require('./App');
var apps = [];
GetContent.prototype = Object.create(View.prototype);
GetContent.prototype.constructor = GetContent;
GetContent.DEFAULT_OPTIONS = {};
function GetContent() {
View.apply(this, arguments);
GetData();
}
function GetData() {
$.ajax({
type: "GET",
url: "/LocalPlatFormService.svc/GetJobRCompanies",
contentType: "application/json; charset=utf-8",
success: ajaxCallSucceed,
dataType: "json"
});
}
function ajaxCallSucceed(response) {
var finalStr = '';
var a = response[0].Success;
if (a.toString().toLowerCase() == "true") {
for (var i = 0; i < response.length; i++) {
var strId = response[i].Id;
var strSuccess = response[i].Success;
finalStr += i + '.' + strId + ' , ' + strSuccess + ' ';
var app1 = new App({});
app1.AddPages(response[i].ImageLarge, response[i].Description, response.length, i);
apps.push(app1);
}
}
else {
alert("No Data Found.");
}
}
module.exports = GetContent;
});
The Ajax call in GetData() is works fine, and it also calls ajaxCallSucceed() on successful Call. but problem is that ajaxCallSucceed() executes after executing all other function, even after executing module.exports = GetContent; in last line.
I want to bind some values in ajaxCallSucceed() based on getting data from database
but how to fetch value from ajaxCallSucceed(), as it is executing after all other operation.
Thanks.
Set ajax async to false. Like this:
$.ajax({
type: "GET",
async: false,
url: "/LocalPlatFormService.svc/GetJobRCompanies",
contentType: "application/json; charset=utf-8",
success: ajaxCallSucceed,
dataType: "json"
});
Setting async to false means that the statement you are calling has to complete before the next statement in your function can be called. If you set async: true then that statement will begin it's execution and the next statement will be called regardless of whether the async statement has completed yet.
I've two problems with this code.
1 $(container + ' meta[data-level="' + level + '"]').length == 0 is always zero
I know this because I create extra call create_views(1); which should not get added, but it gets appended anyhow.
2 dpUniSlider doesn't work as it doesn't see li created via ajax call. If I move it into success message it works fine, but outside function does not. Problem is if I include it inside ajax success it will get called several times as it is under a loop
//Show levels using ajax, before slider is activated
function create_views(level) {
$.ajax({
url: "actions.php",
type: "GET",
data: "show_level=" + level,
cache: false,
success: function (data) {
var view = '<li data-level="' + level + '">' + data + '</li>';
var container = ".slides_container";
if ($(container + ' meta[data-level="' + level + '"]').length == 0) {
$(container).append(view);
} else { //check if element exists, if yes overwrite it.
//$(container + ' meta[data-level="' + level + '"]').replaceWith(view);
alert("Exists");
}
}
});
}
//Loop through all levels and display views
//level count can be rewritten to come from DB and not be hardcoded like now
var levels = 2;
for (var i = 1; i <= levels; i++) {
create_views(i);
} // for loop
create_views(1); //test, delete this
//Activate slide
var unislider = $(".slides_container").dpUniSlider({
//loop: false,
draggable: false
});
For handling multiple parallel asynchronous ajax calls where you want to perform something after they have all completed, you could keep a counter and check in the success callback to see when the last ajax call has succeeded.
It would look like this:
$(function() {
var TOTAL_TASKS = 2,
completedTasks = 0;
function performAjaxTask(taskNumber) {
$.ajax({
url: url,
type: 'GET',
data: data,
cache: false,
success: function(data) {
// Process the data
completedTasks++;
if (completedTasks == TOTAL_TASKS) {
// Perform actions that need to wait until all
// ajax calls have returned successfully.
}
}
});
}
for (var i = 1; i <= TOTAL_TASKS; i++) {
performAjaxTask(i);
}
});
I believe you can use jQuery deferred objects for handling the multiple parallel asynchronous ajax calls where you want to perform something after they have all completed successfully.
Try this:
$(function() {
var LEVELS = 2,
$container = $('.slides_container'),
deferreds = []; // This will hold the deferred objects.
// This function returns a deferred object.
function getViewAndReturnDeffered(level) {
return $.ajax({
url: 'actions.php',
type: 'GET',
data: 'show_level=' + level,
cache: false,
success: function(data) {
var $currentView = $container.find('[data-level="' + level + '"]'),
$newView = '<li data-level="' + level + '">' + data + '</li>';
if ($currentView.length > 0) {
$currentView.replaceWith($newView);
} else
$container.append($newView);
}
}
});
}
for (var i = 1; i <= LEVELS; i++) {
// Put the deferred objects in the array.
deferreds.push(getViewAndReturnDeffered(i));
}
// The function passed to `.done()` will execute when all the deferred
// objects have completed successfully.
$.when.apply($, deferreds).done(function() {
var unislider = $container.dpUniSlider({
//loop: false,
draggable: false
});
});
});
Do you have a <meta></meta> inside .container? Probably not. Use
$(container + ' li[data-level="' + level + '"]')
I am making several jQuery ajax calls within a loop. Each time one of the ajax calls return I need to reference a value corresponding to the original ajax call. My current code doesn't work properly, in that the value of the lskey variable has been altered by further loop iterations.
Here is the code:
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
success: function (data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(lskey); // Remove the relevant localStorage entry
}
, error: function (data) { $('#rollinginfo').append('<br />ERR:' + data); }
});
}
}
The problem is that lskey is being altered each time the loop executes, and therefore the success callback does not have a reference to the value of lskey that existed at the time of the call.
How do I reference the correct value of lskey for each success callback?
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
local_lskey: lskey
success: function (data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(this.local_lskey); // Remove the relevant localStorage entry
}
, error: function (data) { $('#rollinginfo').append('<br />ERR:' + data); }
});
}
}
This should work.
In the end I added the key info to the server posting, and then returned it from the server in JSON format so the success function could then simply refer to the key contained in the server response.
Have you considered chaining the AJAX calls? Basically you can make one AJAX call, process the result, modify lskey, etc. Then when you are ready, increment i and issue the second AJAX call. Loop this way instead of using the for loop...
You could put your ajax call into its own function and pass the lskey and postData values in. That way localStorage.removeItem(lskey) will refer to the lskey variable in the context of the function rather than the context of the loop.
Example
Declare the function -
function postForm(postdata, lskey) {
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
success: function(data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(lskey); // Remove the relevant localStorage entry
},
error: function(data) {
$('#rollinginfo').append('<br />ERR:' + data);
}
});
}
Then you can call your function from your loop -
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
postForm(postdata, lskey);
}
}
You could also declare the function just before the loop (assigning it to a variable) and then call it within the loop.
var postForm = function(postdata, lskey) {
$.ajax({
type: "POST",
async: "false",
url: "/Profile/PostForm",
data: postdata,
success: function(data) {
$('#rollinginfo').append('<br>' + data + ',key=' + lskey);
localStorage.removeItem(lskey); // Remove the relevant localStorage entry
},
error: function(data) {
$('#rollinginfo').append('<br />ERR:' + data);
}
});
}
for (var i = 0, len = localStorage.length; i < len; i++) {
var lskey = localStorage.key(i);
if (lskey.substr(0, 4) === 'form') {
var postdata = localStorage.getItem(lskey); // Get the form data
postForm(postdata, lskey);
}
}