Need help converting API JSON array to key-value object for database update in Wappler

Hello Everyone!

I’m using an API that returns data in this format:

{
  "extractedData": [
    { "name": "CardNo", "value": "857392641" },
    { "name": "DateOfBirth", "value": "15/07/1994" },
    { "name": "DocType", "value": "Resident Identity Card" },
    { "name": "Nationality", "value": "Nepal" },
    { "name": "EmpFirstName", "value": "Ravi" },
    { "name": "EmpLastName", "value": "Sharma" }
  ]
}

I want to convert this array into a key-value object like this:

{
  "CardNo": "857392641",
  "DateOfBirth": "15/07/1994",
  "DocType": "Resident Identity Card",
  "Nationality": "Nepal",
  "EmpFirstName": "Ravi",
  "EmpLastName": "Sharma"
}

My goal is to use this transformed data in a Database Update step to map each key to a specific column (for example: emp_first = EmpFirstName, emp_last = EmpLastName, etc.).

Could someone guide me on the correct way to perform this transformation and use the result in the Database Updatestep?

Any working example or best practice would be really helpful.

If you are happy using a bit of node code this should do it.

const result = data.extractedData.reduce((acc, item) => {
acc[item.name] = item.value;
return acc;
}, {});

Noob Question: Where should I put these codes in my flow.

Currently I’m storing these values in a separate table Under repeat > insert After that I’m using that table (DocsProcessedTable) to update those data to my primary table (EmpDetails)

Can you give more detail,not clear what you mean

Current Scenario:

  1. I’m getting this output from API.
  1. I’m storing this output in a database table.

Like this:

  1. After storing values in this table, I’m using these values to update my primary table which is EmployeeDetailsTable

I want to avoid Step 02 i.e storing values to a separate table. I want to directly update EmployeeDetailsTable from the API output data.

For that I want API output like this:

I am clearly misunderstanding something, why not just use the same workflow but update the main table directly rather than using an intermediate?

Because API output data is not consistent. It’s an AI data processor. For each type of document, it generates different output.

It’s is possible to directly update the primary table within the workflow rather than inserting and then updating. But for that I need the output in this format.

I’m unable to generate output like this.

Ah, i follow now.

You will need to use the node function i listed earlier (not tested but should work). Ideally you should to convert it to a server connect custom module. Do you know how to do that?

Great utility for running js code. I use it often.

1 Like

You'll find that several standard collection/array functions available in Node.js are not yet available in Wappler's serverconnect framework. It definitely takes experimenting, help from AI, and patience. I was able to create a new object using a Set Value element and the code below:

responseAPI.extractedData.groupBy('name')

This gave the following output:

{"CardNo":[{"name":"CardNo","value":"857392641"}],"DateOfBirth":[{"name":"DateOfBirth","value":"15/07/1994"}],"DocType":[{"name":"DocType","value":"Resident Identity Card"}],"Nationality":[{"name":"Nationality","value":"Nepal"}],"EmpFirstName":[{"name":"EmpFirstName","value":"Ravi"}],"EmpLastName":[{"name":"EmpLastName","value":"Sharma"}]}

While this now has your "name" values as the key, you'll need to find a way in Wappler to extract the value from the array that follows each key. I tried several different methods but was unsuccessful at merging this into a new object using available Wappler collections functions.

AI can certainly write Node.js code to handle this issue. It would be rather simple in javascript to solve. Adding custom extensions isn't hard at all in Wappler and your best bet might be using AI to write you the code to convert the API response to your desired object and map it to your table column names.

I’m doing something wrong.

You need to add a line in the end:

return result;
{
    "status": "500",
    "message": "data is not defined",
    "stack": "RunJS:1\n( function() { const result = data.extractedData.reduce((acc, item) => {\n                              ^\n\nReferenceError: data is not defined\n    at RunJS:1:31\n    at RunJS:5:19\n    at Script.runInContext (node:vm:149:12)\n    at exports.run (/Users/user/Documents/projects/nodejs/app_sys/extensions/server_connect/modules/runjs.js:13:29)\n    at App._exec (/Users/user/Documents/projects/nodejs/app_sys/lib/core/app.js:722:49)\n    at App._exec (/Users/user/Documents/projects/nodejs/app_sys/lib/core/app.js:689:20)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async App.exec (/Users/user/Documents/projects/nodejs/app_sys/lib/core/app.js:655:5)\n    at async App.repeat (/Users/user/Documents/projects/nodejs/app_sys/lib/modules/core.js:86:21)\n    at async App._exec (/Users/user/Documents/projects/nodejs/app_sys/lib/core/app.js:722:22)"
}

Looks like the schema may not contain the "data" prefix

try const result = extractedData.reduce.........

I’ve already tried, It’s throwing error for that also.

can you show the actual data schema returned by the API call (I assume you have generated the schema via the API component). What is the APi you are using?

This error is not related to the data returned by the API call, but rather not configuring RunJS correctly to inject the object/variable into the RunJS environment

Unfortunately, it's been a long time since I've used this, so I can't point exactly how to fix it, but it's related to the Data properties in the RunJS step

You're injecting variable "type", not "data", so the whatever RunJS executes it doesn't know variable "data"

Likewise, never actually used server based RunJS, always just make a custom extension so it becomes reusable

:robot: Claude Sonnet 4 solved it.

The New Approach:

  1. Extract entities: First, we process the API response into a clean array with type and mentionText fields.

  2. Individual setvalue steps: Instead of trying to build an object dynamically, I create individual steps for each expected field:

    • CardNo

    • DateOfBirth

    • DocType

    • Nationality

    • EmpFirstName

    • EmpLastName

  3. Safe extraction: Each step uses the where formatter to find the entity by type and extracts the mentionText, with a fallback to empty string if not found:

  4. "value": "{{entities.where('type', '==', 'CardNo')[0].mentionText.default('')}}"
    
    1. Final object: The last step creates the final object structure using all the extracted values:
  5. {
      "CardNo": "{{CardNo}}",
      "DateOfBirth": "{{DateOfBirth}}",
      "DocType": "{{DocType}}",
      "Nationality": "{{Nationality}}",
      "EmpFirstName": "{{EmpFirstName}}",
      "EmpLastName": "{{EmpLastName}}"
    }
    
    

This is Google Documents AI API output:

"entities": [
        {
            "type": "Address",
            "mentionText": "DUBAI, UAE,"
        },
        {
            "type": "DateOfBirth",
            "mentionText": "15/10/2005"
        },
        {
            "type": "DocType",
            "mentionText": "REGISTRATION ID CARD FORM"
        },
        {
            "type": "EmpFirstName",
            "mentionText": "Rayan"
        },
        {
            "type": "EmpLastName",
            "mentionText": "Tumukunde"
        },
        {
            "type": "EmpMiddleName",
            "mentionText": "Kamomo"
        },
        {
            "type": "EmpName",
            "mentionText": "Rayan Kamomo Tumukunde"
        },
        {
            "type": "Gender",
            "mentionText": "FEMALE"
        },
        {
            "type": "Nationality",
            "mentionText": "UK"
        },
        {
            "type": "UID_No",
            "mentionText": "2234232323"
        },
        {
            "type": "Visa_File_No",
            "mentionText": "432/567/7/87567654"
        }
    ]

:+1: Getting Expected Output (Thanks to Claude Sonnet 4):

 "extractedData": {
        "CardNo": "",
        "DateOfBirth": "15/10/2005",
        "DocType": "REGISTRATION ID CARD FORM",
        "Nationality": "UGANDA",
        "EmpFirstName": "Rayan",
        "EmpLastName": "Tumukunde"
    }

FLOW created/updated by Claude Sonnet 4 AI.

Use the Group step to create an object. Name it extractedData. Move the Set Value steps into it and delete the last step and enable their outputs.