Daml Syntax Help

I have the trigger code below, and I’m wondering if I can write a do block inside a filter’s callback function. I’ve written in a comment in the code “NEED HELP HERE”

when trying to build, I get daml/AcceptSwapTrigger.daml:36:13: error: parse error (possibly incorrect indentation or mismatched brackets)

But my IDE is acting strange and it’s not giving me any red error squiggles. And I’m not sure what might be causing my IDE to do that. I’ve tried to launch Daml studio, and followed the steps for installing it in PATH, etc, but that wasn’t working either.

acceptSwapTrigger: T.Trigger ()
acceptSwapTrigger = T.Trigger 
 { initialize = pure (),
  updateState = \_  -> pure (),
  registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @Asset, T.registeredTemplate @Trade, T.registeredTemplate @AssetHoldingAccount, T.registeredTemplate @TransferPreApproval],
  rule = \p -> do
    tradeRequests <- T.query @Trade
    allAssetContracts <- T.query @Asset

    let isMyIncomingTrades = (\tradeRequests -> tradeRequests.receiver == p)
    let myTrades = filter (\(_, contract) -> isMyIncomingTrades contract) tradeRequests



    debug ("asset holding account invites", myTrades)

    
    unless ( DA.Foldable.null myTrades ) do 
      case myTrades of 
        [] -> pure ()

        (tradeCid, c) :: _ -> do
          let isRequestedAsset = (\asset -> do
             -- NEED HELP HERE, isRequestedAsset is a filter function. 
             -- Can I use "do" here? I want to compare a fetched contract's attribute
            requestedAssetTxPreApproval <- T.queryContractId p c.requestedAssetsTxPreApprovalCid
          
             asset.assetType == requestedAssetTxPreApproval.asset.assetType && asset.owner == p)
          let requestedAssets = filter(\(cid,contract) -> isRequestedAsset contract) allAssetContracts
          debug("REQUESTED ASSETS", requestedAssets)
          let requestedAssetCids = map fst requestedAssets
          T.dedupExercise tradeCid Trade_Settle with 
            requestedAssetCids = requestedAssetCids
    debug $ "TRIGGERED",
  heartbeat = None
}

You need to indent the body of the let binding further than the let itself so

          let isRequestedAsset = (\asset -> do
                -- NEED HELP HERE, isRequestedAsset is a filter function.
                -- Can I use "do" here? I want to compare a fetched contract's attribute
                requestedAssetTxPreApproval <- T.queryContractId p c.requestedAssetsTxPreApprovalCid
                asset.assetType == requestedAssetTxPreApproval.asset.assetType && asset.owner == p)

Your next issue is that queryContractId does not take a party argument for triggers so drop that:

requestedAssetTxPreApproval <- T.queryContractId c.requestedAssetsTxPreApprovalCid

Next, your filter function needs to work in TriggerA so you need to use filterA and pure in the filter function.
Finally, queryContractId returns an Optional so you need to handle the case where it’s not present. Putting the last two fixes together you get

          let isRequestedAsset = (\asset -> do
                -- NEED HELP HERE, isRequestedAsset is a filter function.
                -- Can I use "do" here? I want to compare a fetched contract's attribute
                requestedAssetTxPreApproval <- T.queryContractId c.requestedAssetsTxPreApprovalCid
                pure $ optional False (\preapproval -> asset.assetType == preapproval.asset.assetType && asset.owner == p) requestedAssetTxPreApproval)
          requestedAssets <- filterA (\(cid,contract) -> isRequestedAsset contract) allAssetContracts

which compiles fine.

As for why vscode doesn’t show issues, take a look at View → Output → Select daml language server from the drop down and see if there’s anything in there. Also try Ctrl/Cmd-Shift-P → reload window and see if the issue disappears.