Repository: jsonata-js/jsonata
Pull request #555 (2021-12-10 20:44:30)

Fixing reported issue https://github.com/jsonata-js/jsonata/issues/547
@andrew-coleman  this PR fixes an issue reported in https://github.com/jsonata-js/jsonata/issues/547 where jsonata 1.8.5 throws an error(**Key in object structure must evaluate to a string; got: undefined**) when an empty array is passed in.

Signed-off-by: Ke Xu <ke.xu@ibm.com>

coveralls: 
[![Coverage Status](https://coveralls.io/builds/45239916/badge)](https://coveralls.io/builds/45239916)

Coverage remained the same at 100.0% when pulling **4c6cb1be67235f6a6f4a1487839a44c55f6d37be on kexuibm:issue-547** into **e6e436d44e2b04a7dd7b5f9c608a03837be07932 on jsonata-js:master**.

kexuibm: Per request from @andrew-coleman, I added unit test coverage for the defect fix.

Patch:
diff --git a/src/jsonata.js b/src/jsonata.js
index d619890..19b0940 100644
--- a/src/jsonata.js
+++ b/src/jsonata.js
@@ -922,7 +922,7 @@ var jsonata = (function() {
                 var pair = expr.lhs[pairIndex];
                 var key = yield * evaluate(pair[0], reduce ? item['@'] : item, env);
                 // key has to be a string
-                if (typeof  key !== 'string') {
+                if (typeof  key !== 'string' && key !== undefined) {
                     throw {
                         code: "T1003",
                         stack: (new Error()).stack,
@@ -930,24 +930,27 @@ var jsonata = (function() {
                         value: key
                     };
                 }
-                var entry = {data: item, exprIndex: pairIndex};
-                if (groups.hasOwnProperty(key)) {
-                    // a value already exists in this slot
-                    if(groups[key].exprIndex !== pairIndex) {
-                        // this key has been generated by another expression in this group
-                        // when multiple key expressions evaluate to the same key, then error D1009 must be thrown
-                        throw {
-                            code: "D1009",
-                            stack: (new Error()).stack,
-                            position: expr.position,
-                            value: key
-                        };
-                    }
 
-                    // append it as an array
-                    groups[key].data = fn.append(groups[key].data, item);
-                } else {
-                    groups[key] = entry;
+                if (key !== undefined) {
+                    var entry = {data: item, exprIndex: pairIndex};
+                    if (groups.hasOwnProperty(key)) {
+                        // a value already exists in this slot
+                        if(groups[key].exprIndex !== pairIndex) {
+                            // this key has been generated by another expression in this group
+                            // when multiple key expressions evaluate to the same key, then error D1009 must be thrown
+                            throw {
+                                code: "D1009",
+                                stack: (new Error()).stack,
+                                position: expr.position,
+                                value: key
+                            };
+                        }
+
+                        // append it as an array
+                        groups[key].data = fn.append(groups[key].data, item);
+                    } else {
+                        groups[key] = entry;
+                    }
                 }
             }
         }


Test patch:
diff --git a/test/test-suite/groups/object-constructor/case026.json b/test/test-suite/groups/object-constructor/case026.json
new file mode 100644
index 0000000..b08f49a
--- /dev/null
+++ b/test/test-suite/groups/object-constructor/case026.json
@@ -0,0 +1,6 @@
+{
+    "expr": "$${id:{'label':label,'value':value}}",
+    "data": [],
+    "bindings": {},
+    "result": {}
+}