Search code examples
jsonata

JSONata Add external object to array of objects


With JSONata how do I add external data to an existing array, I have an array of phone numbers, I want to call them communications, I can create the array but I want to add the email as a communications type but its outside of the array.

"customer": {
"email": "joe@home.com",
"doNotEmail":"true",
"phones": [
      {
        "key": "0",
        "number": "2222222222",
        "preferredContactTime": "UNKNOWN",
        "sendTextMessages": false,
        "type": "HOME"
      },
      {
        "key": "1",
        "number": "3333333333",
        "preferredContactTime": "UNKNOWN",
        "sendTextMessages": false,
        "type": "HOME"
      },
      {
        "key": "2",
        "number": "2222222222",
        "preferredContactTime": "UNKNOWN",
        "sendTextMessages": false,
        "type": "HOME"
      }
    ]
}

Tried:

"communication": $append(customer.phones.{
"channelType": "Phone",
"channelCode": type,
"completeNumber": number
},{$$.customer.email, $$.customer.privacy.okToContact),

Expeting:

"communication": [
    {
        "emailAddress": "joe@home.com",
        "channelType": "Email",
        "channelCode": "Personal",
        "privacy": [
            {
                "okToContact": true
            }
        ]
    },
    {
        "channelType": "Phone",
        "channelCode": "Home",
        "completeNumber": "222-222-2222"
    },
    {
        "channelType": "Phone",
        "channelCode": "Home",
        "completeNumber": "333-333-3333"
    },
    {
        "channelType": "Phone",
        "channelCode": "Home",
        "completeNumber": "222-222-2222"
    }
]

Solution

  • You want to build your array of phones using the Object constructor -- $.customer.phones.(...) : returns Array -- and then pass that result to the $append() function with an Array containing your email object.

    It looks like your main problem was attempting to provide a non-array (object) to $append() along with a few bracket matching issues.

    Corrected example:

    {
        "communication": $append(customer.phones.{
            "channelType": "Phone",
            "channelCode": type,
            "completeNumber": number
        },[ /* You were missing the square brackets here to denote an array */
            {
                "emailAddress": $$.customer.email, 
                "privacy": [
                    {"okToContact": $$.customer.doNotEmail}
                ]
            }
        ])
    }
    
    

    Corrected Playground: https://try.jsonata.org/xla-fmgxt


    I went a little overboard and took the liberty of making a few changes to your query. Feel free to ignore everything below.

    {
        "communication": $append(
            [{
                "emailAddress": customer.email,
                "channelType": "Email", /* Does not appear in data -- assuming hardcode*/
                "channelCode": "Personal", /* Does not appear in data -- assuming hardcode*/
                "privacy": [
                    {
                        /* I'm assuming this is what you meant, since it's NOT ok to email them */
                        "okToContact": $.customer.doNotEmail = "false" 
                    }
                ]
            }],
            $.customer.phones.(
                /* Defining a format function here -- Just an example, you can probably do this better */
                $formatPhone := function($v) { $v and $length($v) = 10 ? $substring($v, 0, 3) & '-' & $substring($v, 3, 3) & '-' & $substring($v, 6, 4)  : "" };
                { 
                    "channelType": "Phone", /* Does not appear in data -- assuming hardcode*/
                    "channelCode": type, 
                    "completeNumber": $formatPhone(number)
                }
            )
        )
    }
    

    Note: The phone formatting appeared out-of-scope for this question, so I just added a simple function for completeness. You probably want to use something a bit better than I provided for your production code.

    Output:

    {
      "communication": [
        {
          "emailAddress": "joe@home.com",
          "channelType": "Email",
          "channelCode": "Personal",
          "privacy": [
            {
              "okToContact": false
            }
          ]
        },
        {
          "channelType": "Phone",
          "channelCode": "HOME",
          "completeNumber": "222-222-2222"
        },
        {
          "channelType": "Phone",
          "channelCode": "HOME",
          "completeNumber": "333-333-3333"
        },
        {
          "channelType": "Phone",
          "channelCode": "HOME",
          "completeNumber": "222-222-2222"
        }
      ]
    }
    

    Working Playground: https://try.jsonata.org/ozzmi3C4X