Pro-Tip: Populating an array in a JScript script extension and using the array in JavaScript
I'm writing this post not to report a problem or to ask a question but simply to pass along some information to save others the headache I gave myself today. I should have realized my mistake a lot sooner than I did but, in the meantime, I learned something valuable about debugging a script extension and one of the "gotchas" that you may run into.
Scenario:
I wanted to build a runtime object in a script extension that, upon retrieving some data from a datasource, would populate an array that is a property of the script extension. I then wanted to be able to access and iterate through that array in various projects. The script extension is built using JScript and the projects are written in JavaScript (perhaps some of you already see where this is going).
Extension:
Here is a simple mock up of what is in the extension. It's a bit more involved than this but, for illustration purposes, I've simplified this down to the essentials
var myArray = []; function getMyArray() { //This is the "get" routine for getting the property for my runtime object return myArray; } function populateArray() { //This is where the DDT object is created, run through, etc, to get my data. For the purpose of the illustration, I'm simply hardcoding a for loop to populate the array with some objects for(var i=0;i < 10;i++) { myArray[i] = {property1: 'Value1', property2: 'Value2'}; } }
Now, when I have this code loaded up into TestComplete in a JScript project and throw some watches on the variables, I see my array populate and I end up with a 10 element array, each element being an object with the two indicated properties and values.
Using the Extension:
So, I encapsulate that in my script extension, drop it into the appropriate folder, install it in TestComplete and attempt to run the following code in a JavaScript project
function iterateArray() { for(var i = 0; i < extension.myArray.length; i++) { Log.Message('Object ' + i + ' property 1 value: ' + extension.myArray[i].property1); } }
Here's where I get the problem... I get an error that property1 is not a valid property of "undefined". Doing a watch, I see that my array is populated and it has the correct length, but instead of each element being an object, each element is marked as "undefined". What gives?!?!
Well... here's why...
JavaScript, as it is implemented in TestComplete, has some issues with working with the values of indexed properties of objects. While, generally speaking, if I created an array in JavaScript and worked with that JavaScript native array in my JavaScript project, I wouldn't have this issue. However, it appears that, because the JScript array is encapsulated in another object and is, therefore, an object with an indexed property, I need to use a different methodology for retrieving the values.
Solution:
Once I realized this, I modified my code in my JavaScript project as such:
function iterateArray() {
var currentObject for(var i = 0; i < extension.myArray.length; i++) { currentObject = extension.myArray.$get(aqConvert.IntToStr(i));
Log.Message('Object ' + i + ' property 1 value: ' + currentObject.property1); }
And voila! it works.
Now, if I was using the extension in a JScript project, this wouldn't be a problem. But, as it is, because of JavaScripts peculiarities, this was the solution I ended up with.
Of course, there's probably all sorts of other ways of doing this... but this is how I got rid of my headache today.