Search code examples
muledataweavemulesoftmule4anypoint-platform

Need to combine two payloads according to corresponding objects


Is there a way to combine the below payloads as mentioned. We want the 'address' from payload2 to be put in the payload1.errors according to the 'uniqueID' with the 'result' value updated. If payload2 has objects without corresponding uniqueID in payload1.errors, output still should have the object with address field and uniqueID, for example uniqueID = 4 in payload2.

Fields in payload1.errors will be subset of fields in payload2 except the 'address' field.

Please note: These are just samples and actual payloads have more than 10 objects and more than 50 fields for each object.

payload1:

 {
  "metadata": {
    "SchoolName": "ABC High School",
    "quarter": "2021 Q4",
    "ID": "4sdfsdd-esdf-esad1-8asfs7"
  },
  "result": "data-validation-error",
  "errors": [
    {
      "uniqueID": "1",
      "standard": "Must Be Equal to V",
      "marks": "Must Be Equal to 90+",
      "rollNumber": "Must Be Between 1 and 10"
    },
    {
      "uniqueID": "2",
      "standard": "Must Be Equal to VI",
      "marks": "Must Be Equal to 80+",
      "rollNumber": "Must Be Between 10 and 20"
    },
    {
      "uniqueID": "3",
      "standard": "Must Be Equal to VII",
      "marks": "Must Be Equal to 85+",
      "rollNumber": "Must Be Between 30 and 40"
    },
    {
      "uniqueID": "5",
      "standard": "Must Be Equal to XI",
      "marks": "Must Be Equal to 90+",
      "rollNumber": "Must Be Between 50 and 60"
    }
  ]
}

And second payload is:

payload2:

[
  {
    "uniqueID": "1",
    "address": "bcod4001c",
    "admissionDate": "2025-03-28",
    "parentDetails": "N/A",
    "standard": "VIII",
    "marks": "80",
    "rollNumber": "14"
    
  },
  {
    "uniqueID": "2",
    "address": "bhoe4001d",
    "admissionDate": "2021-04-21",
    "parentDetails": "N/A",
    "standard": "IX",
    "marks": "76",
    "rollNumber": "4"
  },
  {
    "uniqueID": "3",
    "address": "bmor4001e",
    "admissionDate": "2021-03-28",
    "parentDetails": "N/A",
    "standard": "IV",
    "marks": "75",
    "rollNumber": "9"
  },
  {
    "uniqueID": "4",
    "address": "bmor7001f",
    "admissionDate": "2021-05-18",
    "parentDetails": "N/A",
    "standard": "X",
    "marks": "96",
    "rollNumber": "45"
  }
  
]

Expected output:

{
      "metadata": {
        "SchoolName": "ABC High School",
        "quarter": "2021 Q4",
        "ID": "4sdfsdd-esdf-esad1-8asfs7"
      },
      "result": "data-validation-error and address validation error",
      "errors": [
        {
          "uniqueID": "1",
          "standard": "Must Be Equal to V",
          "marks": "Must Be Equal to 90+",
          "rollNumber": "Must Be Between 1 and 10",
          "address": "bcod4001c is an invalid address"
        },
        {
          "uniqueID": "2",
          "standard": "Must Be Equal to VI",
          "marks": "Must Be Equal to 80+",
          "rollNumber": "Must Be Between 10 and 20",
          "address": "bhoe4001d is an invalid address"
        },
        {
          "uniqueID": "3",
          "standard": "Must Be Equal to VII",
          "marks": "Must Be Equal to 85+",
          "rollNumber": "Must Be Between 30 and 40",
          "address": "bmor4001e is an invalid address"
        },
        {
          "uniqueID": "4",
          "address": "bmor7001f is an invalid address"
        },
        {
          "uniqueID": "5",
          "standard": "Must Be Equal to XI",
          "marks": "Must Be Equal to 85+",
          "rollNumber": "Must Be Between 40 and 60"
        }
      ]
}

Solution

  • You can use update to transform only the errors, join with payload2 first then map each resulting item as desired.

    I used payload 1 as the main payload and put payload2 into a DataWeave variable for simplicity.

    %dw 2.0
    output application/json
    import * from dw::core::Arrays
    import mergeWith from dw::core::Objects
    fun getAddressError(address)=if (address != null) {address: address++ " is an invalid address" } else {}
    var payload2= [
      {
        "uniqueID": "1",
        "address": "bcod4001c",
        "admissionDate": "2025-03-28",
        "parentDetails": "N/A",
        "standard": "VIII",
        "marks": "80",
        "rollNumber": "14"
        
      },
      {
        "uniqueID": "2",
        "address": "bhoe4001d",
        "admissionDate": "2021-04-21",
        "parentDetails": "N/A",
        "standard": "IX",
        "marks": "76",
        "rollNumber": "4"
      },
      {
        "uniqueID": "3",
        "address": "bmor4001e",
        "admissionDate": "2021-03-28",
        "parentDetails": "N/A",
        "standard": "IV",
        "marks": "75",
        "rollNumber": "9"
      },
      {
        "uniqueID": "4",
        "address": "bmor7001f",
        "admissionDate": "2021-05-18",
        "parentDetails": "N/A",
        "standard": "X",
        "marks": "96",
        "rollNumber": "45"
      } 
    ]
    ---
    payload update {
            case errors at .errors ->
                 outerJoin(payload2, errors, (error1) -> error1.uniqueID, (error2) -> error2.uniqueID)
                   map (
                        if ($.r?) ($.r ++ getAddressError($.l.address) ) 
                        else {uniqueId: $.l.uniqueID, (getAddressError($.l.address))}
                   ) 
    }
    

    Output:

    {
      "metadata": {
        "SchoolName": "ABC High School",
        "quarter": "2021 Q4",
        "ID": "4sdfsdd-esdf-esad1-8asfs7"
      },
      "result": "data-validation-error",
      "errors": [
        {
          "uniqueID": "1",
          "standard": "Must Be Equal to V",
          "marks": "Must Be Equal to 90+",
          "rollNumber": "Must Be Between 1 and 10",
          "address": "bcod4001c is an invalid address"
        },
        {
          "uniqueID": "2",
          "standard": "Must Be Equal to VI",
          "marks": "Must Be Equal to 80+",
          "rollNumber": "Must Be Between 10 and 20",
          "address": "bhoe4001d is an invalid address"
        },
        {
          "uniqueID": "3",
          "standard": "Must Be Equal to VII",
          "marks": "Must Be Equal to 85+",
          "rollNumber": "Must Be Between 30 and 40",
          "address": "bmor4001e is an invalid address"
        },
        {
          "uniqueId": "4",
          "address": "bmor7001f is an invalid address"
        },
        {
          "uniqueID": "5",
          "standard": "Must Be Equal to XI",
          "marks": "Must Be Equal to 90+",
          "rollNumber": "Must Be Between 50 and 60"
        }
      ]
    }