Ambiguous expression could be either a parameterless closure expression or an isolated open code block; - arraylist

I'm having the following code block which will create an object with is concatenated string of all objects within "basixCertificateNumbers" array.
def object= jsonSlurper.parseText '''
{
"basixCertificateNumbers": [
{
"basixCertificateNumber": "012-012"
},
{
"basixCertificateNumber": "045-123"
}
]
}
'''
def concatdObj = jsonSlurper.parseText '''
{
"basixNumber" : ""
}
'''
def content = object.each{ entry->
if(entry.value.getClass().name === "java.util.ArrayList"){
for (basixIndex = 0 ; basixIndex < entry.value.size(); basixIndex++){
entry.value[basixIndex].each{ nestedEntry->{
concatdObj.basixNumber = concatdObj.basixNumber + nestedEntry.value + " "
}}
}
concatdObj.basixNumber = concatdObj.basixNumber.substring(0, concatdObj.basixNumber.length() - 1);
}}
I'm currently receiving the following errors:
Ambiguous expression could be either a parameterless closure expression or an isolated open code block;
solution: Add an explicit closure parameter list, e.g. {it -> ...}, or force it to be treated as an open block by giving it a label, e.g. L:{...} # line 41, column 56.
asixIndex].each{ nestedEntry->{
^
Even though the solution suggested is to put the label on it, I'm not sure where would be the optimal way to put it.
The current solution would be remove the "{" after nestedEntry, which will be something like this:
entry.value[basixIndex].each{ nestedEntry->
concatdObj.basixNumber = concatdObj.basixNumber + nestedEntry.value + " "
}
However, I believe this is not an optimal way of doing things, so if anyone would have a better idea. It would be a great help!
My desire output would be:
{
"basixNumber" : "012-012 045-123"
}

You can just do
def content = [
basixNumber: object.basixCertificateNumbers.basixCertificateNumber.join(' ')
]
String jsonOutput = new JsonOutput().toJson(content)
You don't need concatdObj

Related

Expression with String placeholder in the filter part of JsonPath using karate

I am trying to filter my response using JSON Path where one of the condition using a value from a variable but I am not able to map variable properly, so my filter not working properly.
Sample response JSON:
{
"response":[
{
"id":"1234",
"confirmationCode":"abcd"
}
]
}
I am using the below script where I am using variable 'code':
* def Code = 'abcd'
* def value = karate.jsonPath($.response[?(#.confirmationCode == ' + Code +')])
Read the docs carefully please:
* def value = karate.jsonPath(response, "$.response[?(#.confirmationCode=='" + Code + "')]")

Unable to Parse the variable value to the array variable

I was trying to pass the variable 'i' value to a array index 'locations[i]' using below karate code. but throwing an error saying unable to parse. Please suggest be for any changes.
Feature: Verify Branches
Background: For loop implementation
Given url ''
When method GET
Then status 200
* def i = 0
* def z = $.locations[i].zip
* def p = $.locations[i].phone
* def fun =
"""
function(locations){
for (var i = 0; i < locations.length; i++)
{
print(i)
print('Element at Location ' + i +':' + p)
}
}
"""
Scenario: Validate the locations
Given url ''
When method GET
Then status 200
* call fun p
It is hard to make out anything since you have not provided the value of the response. There are many things wrong here. But I'll try.
Take this line:
* def z = $.locations[i].zip
This will not work, Karate does not support variables within JsonPath by default, refer the docs: https://github.com/intuit/karate#jsonpath-filters
And I think you are un-necessarily using JsonPath where normal JavaScript would have been sufficient:
* def z = response.locations[i].zip
Also it seems you are just trying to loop over an array and call a feature. Please refer to the documentation on Data Driven Features.
Take some time and read the docs and examples please, it will be worth your time. One more tip - before I leave you to understand Karate a little better. There is a way to convert a JSON array into another JSON array should you need it:
* def fun = function(x){ return { value: x } }
* def list = [1, 2, 3]
* def res = karate.map(list, fun)
* match res == [{ value: 1 }, { value: 2 }, { value: 3 }]
So there should never be a need for you to manually do a for loop at all.

Lua property accessor

I'm confused by how Lua properties are working in some of the code I'm trying to maintain. I've spent a good amount of time in the Lua documentation before this. So...
There is a function in one of those Lua tables, like this (we'll call this the 'nested tables' example):
function addItem(item)
index = itemTable.getIndex(item.position[1], item.position[2])
itemTable.items[index] = item
end;
a = Xpl3dSwitch { position = { 27, 0, 1, 1} }
itemTable.addItem(a) --doesn't seem to 'register' the position property
whereas
a = Xpl3dSwitch { }
a.position[0] = 27
a.position[1] = 0
itemTable.addItem(a) --this 'registers' the position properties
...etc, seems to work. Why are the position tables not sticking in the 'nested table' example?
Also, regarding 'a = Xpl3dSwitch { }' - is it an object constructor? It's not clear from the Lua 'documentation' what this is.
Look inside the table a and compare them. That should point you in the direction where the error happens.
to look inside a use something like:
function getTableContent(tab, str)
str = str or "table"
for i, v in pairs(tab) do
if type(v) == "table" and v ~= _G then
str = str.."->"..tostring(i)
getTableContent(v, str)
else
print(str.." Index: "..tostring(i).." Value: "..tostring(v))
end
end
end
getTableContent(a)
io.read()
Once you know how the working and the not working one are structured you should be able to make the adjustments needed.
Edit:
Also you could use:
a = Xpl3dSwitch { }
a.position = {27, 0, 1, 1}

Cache a variable in groovy

When I try to access the len-variables at the end of the script I get this error: "Cannot iterate twice! If you want to iterate more that once, add _CACHE explicitely."
How can I fix that?
def src_str = query_string
def src_arr = src_str.split(' ')
def trg_arr = doc['my_index'].values
trg_arr_sorted = [:]
trg_arr.each {
_index['my_index'].get(it, _POSITIONS).each { pos ->
trg_arr_sorted[pos.position] = it
}
}
src_len = src_arr.length
def trg_len = trg_arr_sorted.size()
int[][] matrix = new int[src_len + 1][trg_len + 1]
(src_len + 1).times { matrix[it][0] = it }
(trg_len + 1).times { matrix[0][it] = it }
(1..src_len).each { i ->
(1..trg_len).each { j ->
matrix[i][j] = [matrix[i-1][j] + 1, matrix[i][j-1] + 1,
src_arr[i-1] == trg_arr_sorted[j-1] ? matrix[i-1][j-1] : matrix[i-1][j-1] + 1].min()
}
}
return 100 - (100 * matrix[src_len][trg_len] / max(src_len, trg_len)) // over here !!!
The code calculates a score using the levenshtein distance computed in words. It works perfect except of the scoring in the last line.
Okay problem is solved.
I explicitly had to declare cache and positions:
_index['lang'].get(it, _POSITIONS | _CACHE)
The error wasn't in the last line, but I thought so. I changed the script to debug it, but elasticsearch doesn't reload the new scipt instantly.

websql use select in to get rows from an array

in websql we can request a certain row like this:
tx.executeSql('SELECT * FROM tblSettings where id = ?', [id], function(tx, rs){
// do stuff with the resultset.
},
function errorHandler(tx, e){
// do something upon error.
console.warn('SQL Error: ', e);
});
however, I know regular SQL and figured i should be able to request
var arr = [1, 2, 3];
tx.executeSql('SELECT * FROM tblSettings where id in (?)', [arr], function(tx, rs){
// do stuff with the resultset.
},
function errorHandler(tx, e){
// do something upon error.
console.warn('SQL Error: ', e);
});
but that gives us no results, the result is always empty. if i would remove the [arr] into arr, then the sql would get a variable amount of parameters, so i figured it should be [arr]. otherwise it would require us to add a dynamic amount of question marks (as many as there are id's in the array).
so can anyone see what i'm doing wrong?
aparently, there is no other solution, than to manually add a question mark for every item in your array.
this is actually in the specs on w3.org
var q = "";
for each (var i in labels)
q += (q == "" ? "" : ", ") + "?";
// later to be used as such:
t.executeSql('SELECT id FROM docs WHERE label IN (' + q + ')', labels, function (t, d) {
// do stuff with result...
});
more info here: http://www.w3.org/TR/webdatabase/#introduction (at the end of the introduction)
however, at the moment i created a helper function that creates such a string for me
might be better than the above, might not, i haven't done any performance testing.
this is what i use now
var createParamString = function(arr){
return _(arr).map(function(){ return "?"; }).join(',');
}
// when called like this:
createparamString([1,2,3,4,5]); // >> returns ?,?,?,?,?
this however makes use of the underscore.js library we have in our project.
Good answer. It was interesting to read an explanation in the official documentation.
I see this question was answered in 2012. I tried it in Google 37 exactly as it is recommened and this is what I got.
Data on input: (I outlined them with the black pencil)
Chrome complains:
So it accepts as many question signs as many input parameters are given. (Let us pay attention that although array is passed it's treated as one parameter)
Eventually I came up to this solution:
var activeItemIds = [1,2,3];
var q = "";
for (var i=0; i< activeItemIds.length; i++) {
q += '"' + activeItemIds[i] + '", ';
}
q= q.substring(0, q.length - 2);
var query = 'SELECT "id" FROM "products" WHERE "id" IN (' + q + ')';
_db.transaction(function (tx) {
tx.executeSql(query, [], function (tx, results1) {
console.log(results1);
debugger;
}, function (a, b) {
console.warn(a);
console.warn(b);
})
})