DataWeave's update Function (2024)

If you're interested in the "why" behind the update function, read on! If you're only interested in knowing how to use it, skip to "The update Function"

Do you remember the first time you were using Mule 4 and you needed to update just a single value in your payload? If you were lucky, you had a flat Object that you needed to update:

{ "one" : 1, "two" : 2, "three" : "whoops"}

Although it's admittedly a little cumbersome, it's easy enough to change that "whoops" into a 3:

payload mapObject (v,k,i) -> if (k ~= "three") {(k): 3} else {(k): v}

It's cumbersome because not only do you need to identify which value you'd like to update, you also need to explictly define what to do with the values you dont want to update. You have to do this because all values in DataWeave are immutable. You cannot modify a value in-place like you can with Python (e.g. obj["three"] = 3)

If your payload is an Array of flat Objects, its a bit more cumbersome, but still easily accomplished. You just map over the Array and use mapObject to do the updates:

payload map ($ mapObject (v,k,i) -> if (k ~= "three") {(k): 3} else {(k): v})

What if your payload is more complex? What if you needed to mask a password that was nested deep in the data structure like this:

{ "one" : 1, "two" : 2, "three" : { "one" : 1, "two" : 2, "three" : { "password" : "mask me!" } }}

How would you approach this problem?

You could take the brute-force approach:

payload mapObject (v,k,i) -> if (k ~= "three") {(k): v mapObject (v,k,i) -> if (k ~= "three") {(k): v mapObject (v,k,i) -> if (k ~= "password") {(k): "*****"} else {(k): v} } else {(k): v} } else {(k): v}

It's not very elegant, is it? It's not easy to understand the purpose of the code, either. You can't reuse it because the keys (i.e., "three", "password") are hardcoded. You can't use it on other data structures because this function wouldn't know what to do if it was passed an Array. Aside from the fact that this solution works, it leaves a lot to be desired.

Instead of a brute-force approach, you might have read a previous post of mine, recognized this pattern, and implemented the following solution:

fun applyWhenKey(e, fn, predicate) = e match { case is Array -> $ map applyWhenKey($, fn, predicate) case is Object -> $ mapObject ((v, k) -> if (predicate(k)) {(k): fn(v)} else {(k): applyWhenKey(v, fn, predicate)}) else -> $ }---applyWhenKey( payload, ((v) -> "*****"), ((k) -> k ~= "password"))

This is a significant improvement over the brute-force approach. You now have a reusable function that's easy to understand if you have a good grasp on recursion.

Let's modify the previous example just slightly:

{ "one" : 1, "two" : 2, "three" : { "one" : 1, "two" : 2, "three" : { "password" : "mask me!" }, "password" : "don't worry about me!" }}

Now you have one password that you should mask, and another one that you should leave alone. If you try to use the applyWhenKey function, you get this:

{ "one" : 1, "two" : 2, "three" : { "one" : 1, "two" : 2, "three" : { "password" : "*****" }, "password" : "*****" }}

An elegant solution to this problem lies in the update function.

I find the update function is pretty inuitive, and easier to demonstrate than to explain in-depth. Recall our first example:

{ "one" : 1, "two" : 2, "three" : "whoops"}

Here's how we would change "whoops" to 3 using the update function:

import update from dw::util::Values---payload update "three" with 3

Simple, right? This reads easily as, "update payload.three with the value 3," or, "update the payload at key 'three' with the value 3." How about our moderatly complex password example:

{ "one" : 1, "two" : 2, "three" : { "one" : 1, "two" : 2, "three" : { "password" : "mask me!" } }}

Here's how you would mask that password with the update function:

import update from dw::util::Values---payload update ["three", "three", "password"] with "*****"

You could read this as "update payload.three.three.password with *****."

Finally, how about the situation that applyWhenKey could not handle?

{ "one" : 1, "two" : 2, "three" : { "one" : 1, "two" : 2, "three" : { "password" : "mask me!" }, "password" : "don't worry about me!" }}

Since we can target exactly what we want to change, the solution is the same as our previous example:

import update from dw::util::Values---payload update ["three", "three", "password"] with "*****"

The update function gets you away from using recursion or brute-force solutions to solve these problems.

Recap

Here's a quick recap:

  • To use the update function, you must import it from dw::util::Values
  • The update function is paired with another function, with. You do not need to import with.
  • When working with Objects, identify what to update by using Strings. If you need to update an Object more than one level deep, use an Array of Strings.

Working with Arrays

Updating Arrays is simple as well. Instead of using Strings, you use integers to identify the index of the Array you'd like to update:

[1,2,4] update 2 with 3> Returns: [1,2,3]

You deal with nested Arrays in the same way you deal with nested Objects, by using an Array to identify what you'd like to update:

[[1,2],[3,4],[6,6]] update [2,0] with 5> Returns: [[1,2],[3,4],[5,6]]

When Objects and Arrays are in the same data structure, you use Strings and integers as needed to identify what you'd like to update:

{ "one" : 1, "nums" : [1,2,4]} update ["nums", 2] with 3> Returns: {"one": 1, "nums": [1,2,3]}

There's one other piece of data we need to learn how to update: attributes.

Working with Attributes

To identify attributes you'd like to update, you use Strings. Since Strings are already used to update Objects, we need to wrap the String in a helper function, attr, so that the update function knows to look for an attribute and not just an Object key. The attr function needs to be imported from dw::util::Values as well. Here an example payload:

<root> <numbers> <number parity="even">1</number> </numbers> </root>

And here's how you'd update the "parity" attribute:

import attr, update from dw::util::Values---payload update ["root", "numbers", "number", attr("parity")] with "odd"

Updating Objects with Repeated Keys

While the update function is easy to use, there is one complication to consider: updating Objects with repeated keys. You're most likely to come across this edge-case when reading or writing XML. As an example, let's say you wanted to update the following payload so that the "parity" attribute for the number 1 is odd, and you want to leave the number 2 as-is:

<root> <numbers> <number parity="even">1</number> <number parity="even">2</number> </numbers> </root>

You might try to do so like this:

%dw 2.0output application/xmlimport attr, update from dw::util::Values---payload update ["root", "numbers", "number", attr("parity")] with "odd"

But it would return this:

<root> <numbers> <number parity="odd">1</number> <number parity="odd">2</number> </numbers> </root>

When you run into this situation, you can do the following:

  1. Use selectors to isolate the Object you want to update
  2. Transform the Object as needed (likely using mapObject to identify which index of the Object you want to modify)
  3. Use update to insert the updated Object back into the data structure.

Here's how you'd accomplish this with our previous example:

var updatedNumbers = payload.root.numbers // 1) mapObject (v,k,i) -> // 2) if (i == 0) {(k) @(parity: "odd"): v} else {(k): v}---payload update ["root", "numbers"] with updatedNumbers // 3)

Now the update code will return the desired payload:

<root> <numbers> <number parity="odd">1</number> <number parity="even">2</number> </numbers></root>

The update function provides a clean and intuitive interface for updating single values on nested collections. You can easily update values in Array, Objects, as well as attributes. You can find the offical documentation for the update function here. If you have any questions, feel free to leave a comment below, or reach out to me on LinkedIn.

DataWeave's update Function (2024)

FAQs

How do I update a field in DataWeave? ›

update(objectValue: Object, fieldName: String): UpdaterValueProvider<Object> This update function updates a field in an object with the specified string value. The function returns a new object with the specified field and value. Introduced in DataWeave version 2.2.

How do you update a variable in MuleSoft? ›

To update the value from the accumulator variable first we need to get the current value using get(Key) method and after we get the value from the accumulator variable we add a new value and store the updated value in the same variable.

How do I update attributes in Mule 4? ›

You can update Attributes by using Transform Message component. In Transform Message select output as Attributes in the drop-down.

What is $$$ in DataWeave? ›

The $ symbol can be used for accessing the value of a key-value pair in a map. $$ can be used for getting the key (or index) of the key-value pair.

How do you update one field? ›

Press Ctrl + A. Press F9. If your document has tables with fields or formulas, you might need to select each table separately and press F9. Tip: To make sure that you don't forget to update your table of contents before you print the document, set Word to update fields automatically before printing.

How do I update Raml? ›

Change RAML or OAS Version
  1. From the asset details pane, click Add version.
  2. (Required) Select a Method for the API specification.
  3. (Required) From File upload click Choose file. ...
  4. Specify the Main file if the uploaded file is a zip. ...
  5. (Required) In Version , enter a new version for the asset.

How do you update a variable? ›

Updating a variable by adding 1 is called an increment; subtracting 1 is called a decrement. Sometimes programmers also talk about bumping a variable, which means the same as incrementing it by 1.

How do you update a final variable? ›

Final variable in Java cannot be changed. Once if we have assigned the final variable it can not be changed it is fixed. but if you have declare a blank final variable then you can assign value to it only in constructor. also using hiearchical instances can come handy.

How do I update a field value in Salesforce? ›

You can achieve this by using the process builder but the field gets updated whenever we edit/create the record only.In order to update all the existing record you would need to edit and save all the record which need manual effort. So,I would suggest you to go with the batch class to achieve the same.

How do you handle errors in DataWeave? ›

how to handle exception in dataweave? You can catch the exception via flow reference, from the calling flow you would be able to define catch exception strategy to conduct an evaluation of the exception in your dataweave just like this # [exception. causeMatches('com. mulesoft.

How do I append in DataWeave? ›

In DataWeave 2.0, concatenation can be achieved by using the ++ (plus plus) function. However, there are two additional syntax options to concatenate objects and one to concatenate strings in DataWeave. Concatenation is when you link two strings, objects, data types etc together in a chain or series.

Top Articles
Latest Posts
Article information

Author: Rev. Porsche Oberbrunner

Last Updated:

Views: 5374

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Rev. Porsche Oberbrunner

Birthday: 1994-06-25

Address: Suite 153 582 Lubowitz Walks, Port Alfredoborough, IN 72879-2838

Phone: +128413562823324

Job: IT Strategist

Hobby: Video gaming, Basketball, Web surfing, Book restoration, Jogging, Shooting, Fishing

Introduction: My name is Rev. Porsche Oberbrunner, I am a zany, graceful, talented, witty, determined, shiny, enchanting person who loves writing and wants to share my knowledge and understanding with you.