Passing parameters through scripting - javascript

Using Testcomplete (javascript) for our automation.
I have created a function:
function SelectDropdownBoxItem(object, property, item)
{
var dropDown = eval(object + "." + FindChild(property, item, 5));
dropDown.Click();
}
Also tried without using eval...
When I call the method using something like this:
var AutoAddressSuggestionList = Aliases.b.pageGuidewireClaimc.panelBoundlist.AddressSuggestionList;
SelectDropdownBoxItem(AutoAddressSuggestionList,"contentText","1 Something Street*");
I get an error "Object Expected"... I have no idea why, because when I run this method without parameterizing it everything works.
Any ideas?

No need for eval here; you can call the method directly on the object:
var dropDown = object.FindChild(property, item, 5);
Also, it's a good idea to check that the list item was actually found:
if (dropDown.Exists) {
dropDown.Click();
}
else {
Log.Error(
"Drop-down list item was not found.",
"Object: " + object.FullName + "\r\n" +
"Item : " + item
);
}

Related

How to get "numFound" using JSON query for Solr?

I am simply trying to obtain the "numFound" figure from a Solr query in a piece of javascript.
At present the code I have outputs the number of responses, limited to X rows I specify, as well as X number of items.
What I want instead is the "numFound" value in the response, and to store it as a var in my javascript.
In the example below it would be 394.
{
"responseHeader":{
"zkConnected":true,
"status":0,
"QTime":31,
"params":{
"q":"names:\"Leo Varadkar\" AND region:\"ROI\""}},
"response":{"numFound":394,"start":0,"maxScore":11.911881,"docs":[
I don't want any info from the fields of a specific entry or anything like that. In my python code I can obtain such a figure by something like "solr.search(query).hits". However I have been unable to find an equivalent from poking around with this. I have tried to guess something like "data.response.hits" and the like but to no avail. I am really in the dark here!
I have been unable to find clear documentation on how to do this, or an example of someone doing the same thing, despite it seeming like quite an important aspect of the whole point of queries in Solr. Top 50 results are no use to me. I am dealing with tens of thousands of items. My confusion might suggest I am failing to understand some key aspect of the whole thing...but I don't think so?
All I want is that figure. Surely somebody knows how to get it? I bet it's very simple.
My javascript below:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
function on_data(data) {
$('#results').empty();
var docs = data.response.docs;
$.each(docs, function(i, item) {
$('#results').prepend($('<div>' + item.name + '</div>'));
});
var hits = 'Found ' + data.response. + ' hits'
$('#hits').prepend('<div>' + hits + '</div>');
var total = 'Found ' + docs.length + ' results';
$('#results').prepend('<div>' + total + '</div>');
}
function on_search() {
var query = $('#query').val();
if (query.length == 0) {
return;
}
var url='http://localhost:8983/solr/articles/select?q=text:'+query+'&version=2.2&start=0&rows=10000&indent=on&wt=json&callback=?&json.wrf=on_data';
var urlB='http://localhost:8983/solr/articles/select?q=text:'+query+'&version=2.2&start=0&rows=50&indent=on&wt=json&callback=?&json.wrf=on_data';
$.getJSON(urlB);
}
function on_ready() {
$('#search').click(on_search);
/* Hook enter to search */
$('body').keypress(function(e) {
if (e.keyCode == '13') {
on_search();
}
});
}
$(document).ready(on_ready);
The structure is {"response":{"numFound":394 ... }}, which is loaded into your data variable.
var hits = 'Found ' + data.response.numFound + ' hits'
.. should give you the number you're looking for. The hits name is just given by various libraries (probably pysolr in your case) to the same value.
You can also use console.log(data) to see the parsed data structure in your developer tools' console window.

Javascript: sequential, not parallel

I'm working on a project and have trouble to make my javascript work in a sequential way. I know that javascript can execute tasks in parallel so it won't get stuck when you do a request to a server that doesn't respond. This has It's advantages and disadvantages. In my case, It's a pain in the bum.
The scenario is the following, I'm using Firebase to store how many people agree with an opinion. This looks as follows:
I like javascript
- I like it a lot
- I like it
- like nor dislike it
- don't like it
- I basically hate it
People can now select 1 of the options. A record of their selection is then placed under the option. The structure:
-dfd21DeH67 : {
Title : "I like javascript"
options : {
0 : {
option : "I like it a lot"
agrees : {
-dfd21DQH6sq7 : "Jhon"
-dfd21DQH6sq8 : "Luke"
-dfd21DQH6sq9 : "Bruce"
}
}
1 : {
option : "I like it"
agrees : {
-dfd21DQH6sqA : "Harry"
-dfd21DQH6sqB : "Jimmy"
}
}
2 : {
option : "like nor dislike it"
agrees : {
-dfd21DQH6sqC : "Timmy"
-dfd21DQH6sqD : "Paul"
-dfd21DQH6sqE : "Danny"
-dfd21DQH6sqF : "Robin"
-dfd21DQH6sqG : "Dan"
}
}
3 : {
option : "don't like it"
agrees : {
-dfd21DQH6sqH : "Nathan"
-dfd21DQH6sqI : "Jerry"
}
}
4 : {
option : "I basically hate it"
agrees : {
-dfd21DQH6sqJ : "Tony"
}
}
}
}
Now, I want to query it. The results I need for each option are:
- Option (ex. "I like it a lot")
- agree count (ex. n people agreed on this one)
- Percentage (ex. 3 out of 13 said: "I like javascript". this would be ~23%)
Now, getting the "option" and showing this in the browser: success
getting the "agree count": success thanks to numChildren()
getting the "percentage": challenge because I need the sum of them all to calculate this.
Any ideas on how to pull this off? Tried pulling off some callback tricks. Unfortunatly to no avail. Below is my vision:
//javascript
var hash = "-dfd21DeH67";
var fbDB = new Firebase("https://<MyDB>.firebaseio.com/");
var buffer = [];
var sum;
fbDB.child(hash).once("value", function(opinion) {
var thisOpinion = opinion.val();
// First section
$.each(thisOpinion.options, function(i) {
fbPoll.child(hash + "/options/" + i + "/agrees").once("value", function(agrees) {
votes.push(agrees.numChildren());
sum += agrees.numChildren();
});
});
// execute only if the First section is done
// this is currently not the case, this gets executed before
// the first one finishes => result: #ResultsPanel stays empty
$.each(buffer, function(i) {
$("#ResultsPanel").append(
"<div class=\"OptionStatsBlock\">" +
"Option: " + thisOpinion.options[i].option + "<br>" +
"Total: " + buffer[i] + "<br>" +
"Percentage: " + ((buffer[i] / sum) * 100) +
"</div>"
);
});
});
Thanks in advance,
As covered in the comments already: you seem to struggle with the asynchronous nature of Firebase (and most of the modern web). I would encourage you to spend as much time on understanding asynchronous programming as it takes to get rid of the pain it currently causes. It will prevent you far more pain down the line.
One possible solution
Firebase DataSnapshots always contain all data from under the node that you are requesting. So instead of doing a once in a loop (which is almost always a bad idea), you can just request the data one level higher and then loop and use child:
// First section
$.each(thisOpinion.options, function(i) {
var agrees = opinion.child("/options/" + i + "/agrees");
votes.push(agrees.numChildren());
sum += agrees.numChildren();
});
This code executes synchronously.
Note that I didn't test this, so there may be typos. It's basically just a slight modification of your code, that uses DataSnapshot.child: https://www.firebase.com/docs/web/api/datasnapshot/child.html
You can use jQuery Promise to handle this async nature of calls.
http://api.jquery.com/category/deferred-object/
Even this post might help you out -
http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
For one the second $.each is running on an empty buffer array. So it should never even run.
A better approach may be adding an event listener to the "child_added" event similar to below: Referenced from here https://www.firebase.com/docs/web/guide/retrieving-data.html#section-event-types
var ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts");
// Retrieve new posts as they are added to Firebase
ref.on("child_added", function(snapshot) {
var newPost = snapshot.val();
console.log("Author: " + newPost.author);
console.log("Title: " + newPost.title);
});

Passing variable to child function javascript

I've looked at multiple questions in search for an answer however to no avail, I'm trying to obtain the variable from a parent function and passing it like "a(b)" doesn't seem to work
I cannot for the life of me obtain 'item_classes', is there another way in which I can write my code in order for it to be operable
$(document).ready(function () {
$('.nm-more').hover(function () {
var item_num = $(this).data('stg-id');
var item_names = $(this).data('stg-items');
var item_classes = $(this).data('stg-class');
item_names.forEach(function (entry) {
var item_index = item_classes[entry];
alert(entry + ' ' + item_index);
});});
});
});
Here is a jsfiddle http://jsfiddle.net/bgzkge65/25/
Problem solved:
http://jsfiddle.net/bgzkge65/27/
$(document).ready(function () {
$('.nm-more').click(function () {
var item_num = $(this).data('stg-id');
var item_names = $(this).data('stg-items');
var item_classes = ($(this).data('stg-class'));
item_names.forEach(function (entry) {
var item_index = item_classes[item_names.indexOf(entry)];
alert(entry + ' ' + item_index);
});
});
});
And HTML changes:
<li class="nm-more" data-stg-id="2" data-stg-items='["Mark as read", "Mark as unread", "Flag all items", "Unflag all items"]' data-stg-class='["readit", "unreadit", "flagit", "unflagit"]'>Mark all</li>
<li class="nm-more" data-stg-id="1" data-stg-items='["Mark as read", "Mark as unread", "Flag items", "Unflag items"]' data-stg-class='["readit", "unreadit", "flagit", "unflagit"]'>Selected</li>
What I did:
First of all: data-stg-class wasn't formatted as an array. I reformatted and made it an array.
The code was actually correct, but you are using named keys, but you need to use indexes here. So entry should be an index and not a reference to a named key from data-stg-class. So I used item_names.indexOf(entry) to retrieve the proper index and return the correct value.
Instead of array.indexOf, you could also retrieve the index from forEach. It's the second argument of that function, either declare it in the function declaration or retrieve it with arguments[1]. In this case the indexes of both arrays match which makes this alternative solution viable.

javascript: trouble calling function argument

I am having trouble calling an arguement in the functin below.
function makeScales(size,note1,note2,note3,note4,note5,note6,note7,note8){
for(var z=0; z<size; z++){
if(semis=="Sharps"){
notes = notes + " - " + noteSharp["note" + z];
} else {
notes = notes + " - " + noteFlat["note" + z];
}
}
}
I went through many debugging procedures and found that my error en-lies with noteSharp["note" + z] more specifically "note" + z . For example if i do console.log(noteSharp[note1]) i get the desired result and i set z to 7 so i can see that its populating appropriately but I get undefined for my results. Any help would be greatly appreciated.
"note" + z will give you a string like "note1" not an identifier.
If you want to access a piece of data by an index, then put it in an array, not in a variable with a number in its name.
For example:
function makeScales(size, notes) {
//...
notes = notes + " = " + noteSharp[ notes[z] ];
//...
}
makeScales( "some size", [ "foo", "bar", "baz" ] );
Alternatively (and I wouldn't recommend this approach as it mixes different kinds of data in a single data structure), you can use the arguments object.
notes = notes + " - " + arguments[z];
arguments represents all the arguments passed to the function. The second argument (aka note1) will have the index 1 and so on.
Your problem there is that noteSharp[note1] is using the value of the variable note1 as the key to lookup, whereas noteSharp["note" + z] results in a string of "note" followed by the value of z.
To reference a variable name via a string, use eval:
noteSharp[eval("note" + z)];
However, I would highly recommend not using eval. Others do too, but perhaps there is a counterpoint.
Please do this instead, otherwise Cthulhu might arise...
Pass note1, note2, ..., noteN as properties of an object. Therefore you can look up their values exactly as you desire, just one level deeper.
function makeScales(size, notes) {
var z = 1;
var note1 = notes["note" + z];
}
// Calling makeScales with our notes.
makeScales(10, {
note1: 'c',
note2: 'd',
note3: 'e',
// etc.
});

How do I iterate over object literal array with jquery $.each() method?

how do I iterate over object literal array with jquery $.each() method?
In the chrome debugger, it comes back as "undefined, undefined".
Any help would be really appreciated. thanks!
var links = [
{ className : 'hover', url : 'http://www.yahoo.com' },
{ className : 'hover-2', url : 'http://www.foxnews.com' },
];
loopy(links)
function loopy(obj){
$.each(
obj,
function(){
console.log(obj.className + ', ' + obj.url);
}
);
}
Try:
$.each(
obj,
function(i, val){
console.log(val.className + ', ' + val.url);
}
);
The $.each function parameter takes two arguments -- the index of the current item in the array, and the second is the actual current value of the array.
See the API for some more explanation and examples.
You can see this fiddle to see it in action.
I just wanted to offer a slightly modified version of David's response that will be a little more gentle on the DOM when processing larger objects.
Original answer (above):
$.each(
obj,
function(i, val){
console.log(val.className + ', ' + val.url);
}
);
This solution works, but it generates an entirely new instance of the iterator function for every property in the object. There's no need for that, and I think you'll find more stable performance in larger applications by declaring specific methods to handle that sort of thing.
Try this:
// Process a property in your link object
function links_iterationHandler(i, val) {
console.log(val.className + ', ' + val.url);
}
// Traverse the link object and pass each result off to the method above
$.each(obj, links_iterationHandler);
This essentially does the same thing, but doesn't hammer on the DOM as much. It's not a big deal if you only have a few items in your object. But if you're dealing with a lot of data, like a big recordset loaded via Ajax, it will make a difference for sure.
Cheers!
I would try this:
$.each([52, 97], function(index, value) {
alert(index + ': ' + value);
});
The first property is the index.
http://api.jquery.com/jQuery.each/

Categories

Resources