Datatype detail:
type1: Text
type2: [detail2]
Datatype detail2:
type1: Text
template A
with
consumerName: Text
producerName : Text
details : Map Text detail
create A with consumerName,producerName,details
now need to update contract old Details(Map Text Datatypes) with new Details(Map Text Datatypes) of multiple keyvalues .how can be achieve this using merge without doing multiple contract updation or any other solution is possible ?
You can use the functions in DA.Next.Map
to manipulate maps. Here is a complete working example which I hope can shed some light on syntax and simple use-cases:
module Main where
import Daml.Script
import qualified DA.Next.Map as Map
import DA.Next.Map (Map)
template Comments
with
producer: Party
consumer: Party
productComments: Map Text [Text]
where
signatory producer
observer consumer
preconsuming choice AddComment: ContractId Comments
with productName: Text, comment: Text
controller consumer
do
create this with productComments = addComment productComments productName comment
nonconsuming choice ReadComments: Map Text [Text]
with reader: Party
controller reader
do return productComments
addComment: Map Text [Text] -> Text -> Text -> Map Text [Text]
addComment prev item newComment = case Map.lookup item prev of
-- If the key is not in the map yet, we just add the comment
None -> Map.insert item [newComment] prev
-- If there are comments already, add to the end
Some existingComments -> Map.insert item (existingComments ++ [newComment]) prev
setup : Script ()
setup = script do
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")
id1 <- submit bob do
createCmd Comments
with producer = bob
consumer = alice
productComments = mempty -- start with an empty map
map1 <- submit alice do exerciseCmd id1 (ReadComments alice)
assert $ map1 == Map.fromList []
id2 <- submit alice do exerciseCmd id1 (AddComment "item1" "it was not very good")
map2 <- submit alice do exerciseCmd id2 (ReadComments alice)
assert $ map2 == Map.fromList [("item1", ["it was not very good"])]
id3 <- submit alice do exerciseCmd id2 (AddComment "item2" "this is great!")
map3 <- submit alice do exerciseCmd id3 (ReadComments alice)
assert $ map3 == Map.fromList [("item1", ["it was not very good"]),
("item2", ["this is great!"])]
id4 <- submit alice do exerciseCmd id3 (AddComment "item2" "I can't stop raving about it")
map4 <- submit alice do exerciseCmd id4 (ReadComments alice)
assert $ map4 == Map.fromList [("item1", ["it was not very good"]),
("item2", ["this is great!", "I can't stop raving about it"])]
Tested on SDK 1.6.0.
I've also recently answered a possibly related question on the DAML forum, where I have a few more examples of using the functions in DA.Next.Map. Maybe that can help, too.