1
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 ?

arjun a
  • 151
  • 7

1 Answers1

2

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.