我有Product
引用Store
模型。
我希望/stores/1
的响应返回一个也包含引用产品的JSON。类似的东西:
{
data: {
storeName: "Store1",
id: 1
products: {
{ productName : "Product1", productPrice: 10},
{ productName : "Product2", productPrice: 100},
}
}
}
我目前仍然坚持使用Yesod处理程序,将产品注入到正确的位置。
getStoreR :: StoreId -> Handler Value
getStoreR storeId = do
store <- runDB $ get404 storeId
products <- runDB $ selectList [StoreId ==. storeId] []
let productsJson = [entityIdToJSON (Entity k r) | Entity k r <- products]
let storeJson = entityIdToJSON (Entity storeId store)
-- Inject productsJson under "products" property fails
let storeJsonWithProducts = HM.insert "products" productsJson storeJson
return $ object ["data" .= storeJsonWithProducts]
失败了:
Couldn't match expected type ‘HM.HashMap k0 [Value]’
with actual type ‘Value’
Relevant bindings include
storeJsonWithProducts :: HM.HashMap k0 [Value]
(bound at Main.hs:80:9)
In the third argument of ‘HM.insert’, namely ‘storeJson’
In the expression: HM.insert "products" productsJson storeJson
(顺便说一下,我用here创建了一个单独的文件应用程序)
答案 0 :(得分:1)
HashMap.insert
的类型为k -> v -> HashMap k v -> HashMap k v
。您的storeJson
不是HashMap
,而是Value
- 使用Object :: HashMap Text Value -> Value
构造函数创建的v ~ Value
。这意味着~
(如果您不熟悉,可以将productsJson
视为类型相等)。但是,这是一个问题,因为Value
不是[Value]
,而是HashMap
。
因此,要解决您的问题,您需要:
从storeJson
中提取let storeHM = case storeJson of
Object h -> h
。
storeJson
当然,您应该确保正确处理其他构造函数,因为如果Object
未构造productJson
,这将会崩溃。
将Value
转换为Value
。 Array :: Vector Value -> Value
的一个构造函数为Vector Value
,您可以使用[Value]
从Data.Vector.fromList
获得import qualified Data.Vector as V
[...]
let productsValue = Array (V.fromList productsJson)
:
productsValue
最后,将storeHM
插入HashMap
let storeHMWithProducts = HM.insert "products" productsValue storeHM
:
object
然后,您可以继续操作,使用storeHMWithProducts
将Value
再次转换为JSON return $ object ["data" .= storeHMWithProducts]
:
Private Sub Form_Open(Cancel As Integer)
Dim strMyDir As String
Dim intPos As Integer
Dim rst As dao.Recordset
Dim strSQL As String
Dim rstWhatsNew As dao.Recordset
DoCmd.ShowToolbar "Database", acToolbarNo
DoCmd.ShowToolbar "Toolbox", acToolbarNo
DoCmd.ShowToolbar "Form View", acToolbarNo
If Application.GetOption("ShowWindowsInTaskbar") = -1 Then
Application.SetOption "ShowWindowsInTaskbar", 0
End If
If DLookup("Locked", "luLockOut") <> 0 Then
MsgBox "Database is being worked on. Please try back in a couple minutes.", vbInformation, " "
DoCmd.Quit
Else
strSQL = "Select * From tblLastLogins Where UserName = '" & GetCurrentUserName() & "'"