Elm Json 请求不工作?
Elm Json request not working?
在 Elm 中,您可以使用 Json.decode
和 Http package
来请求 json 数据。我的尝试是定期查找电子邮件 ( from this url )。计时器操作确实有效(我用一个简单的计数器尝试过)。
我参考了this example and
现在的类型:
type alias Email = { title: String, ... }
type Action =
NoAction
| TickCounter -- TODO rem
| AddEmails (List Email)
然后主要+状态+动作...
main: Signal Html
main = Signal.map (view actions.address) state
state: Signal Model
state = Signal.foldp update makeEmptyModel input
-- handle inputs (merging signals)
input : Signal Action
input =
Signal.mergeMany
[ actions.signal
-- , other actions
, Signal.map checkForNewMails (Time.every (Time.minute / 6.0) ) -- TODO precise timer (quick test)
]
actions: Signal.Mailbox Action
actions = Signal.mailbox NoAction
update: Action -> Model -> Model
update action model =
case action of
NoAction -> model
TickCounter -> { model | count = model.count + 1 }
AddEmails newMails -> { model | emails = newMails }
checkForNewMails: Time -> Action
checkForNewMails t =
let mails = startGettingEmailData
in TickCounter -- TODO replace with AddEmails using mails
TickCounter
是一个Action,我用它来测试我的计时操作。但问题是startGettingEmailData
。它使用下一个片段,但它不会触发任何 JSON 请求(我已经通过控制台检查过)。一旦这个问题得到解决,我就可以将 mails
转换为一个动作,这样我就可以在模型中添加电子邮件。
-- url to json
jsonUrl = "https://dl.dropboxusercontent.com/u/14070433/temp.json"
-- get emails
startGettingEmailData: Task Http.Error (List Email)
startGettingEmailData = Http.get emailJsonDecoder jsonUrl
emailJsonDecoder: Json.Decoder (List Email)
emailJsonDecoder =
let makeEmail = Json.object4
(\ti fr da bo -> makeNewEmail -1 ti fr da bo )
("title" := Json.string)
("from" := Json.string)
("date" := Json.string)
("body" := Json.string)
in
"emails" := Json.list makeEmail
我的代码有问题吗?如果没有,那么有没有办法检查 Http.Error 内容? (也许问题不在我的代码,而在网络,但我可以通过浏览器访问保管箱文件...)
您的 checkForNewMails
代码实际上并未对 mails
执行任何操作,因此它永远不会被调用。 let
语句不进行任何调用,它只允许您在更大的函数体内定义一次性函数。由于 in
部分只是 returns TickCounter
,那么这意味着此函数只 returns TickCounter
并且什么都不做。
此外,startGettingEmailData
返回 Task
,这意味着它仅在端口中时被调用。你不能在只有 returns 和 Action
的函数中使用它,因为它永远不会得到 运行.
你会想写一个 port
在定时器上触发,然后创建一个 Task
来轮询你的 url,然后映射那个 GET 请求的响应到一个动作,调用 actions
邮箱。您可以使用 Task.onError
编写一个简单的错误处理程序,它可以通过在您的 Action 类型上创建一个 Error String
构造函数来将错误消息转发到您的视图。
这是一个例子:
getEmailData _ =
let
request =
Http.get emailJsonDecoder jsonUrl
|> Task.map AddEmails
in
request
`Task.onError` (\err -> Task.succeed (Error (toString err)))
`Task.andThen` (\action -> Signal.send actions.address action)
port getEmails : Signal (Task a ())
port getEmails =
Signal.map getEmailData (Time.every (Time.minute / 6.0) )
以上代码将导致 URL 被检索、解析,然后,如果成功,它将触发您的 actions
邮箱并导致视图更新。如果有错误,它将发送 Error
的新动作和一条消息,您应该在视图中处理该消息。 (您必须将 Error String
添加到 Action
联合类型,并在模型、更新和视图函数中处理它。
在 Elm 中,您可以使用 Json.decode
和 Http package
来请求 json 数据。我的尝试是定期查找电子邮件 ( from this url )。计时器操作确实有效(我用一个简单的计数器尝试过)。
我参考了this example and
现在的类型:
type alias Email = { title: String, ... }
type Action =
NoAction
| TickCounter -- TODO rem
| AddEmails (List Email)
然后主要+状态+动作...
main: Signal Html
main = Signal.map (view actions.address) state
state: Signal Model
state = Signal.foldp update makeEmptyModel input
-- handle inputs (merging signals)
input : Signal Action
input =
Signal.mergeMany
[ actions.signal
-- , other actions
, Signal.map checkForNewMails (Time.every (Time.minute / 6.0) ) -- TODO precise timer (quick test)
]
actions: Signal.Mailbox Action
actions = Signal.mailbox NoAction
update: Action -> Model -> Model
update action model =
case action of
NoAction -> model
TickCounter -> { model | count = model.count + 1 }
AddEmails newMails -> { model | emails = newMails }
checkForNewMails: Time -> Action
checkForNewMails t =
let mails = startGettingEmailData
in TickCounter -- TODO replace with AddEmails using mails
TickCounter
是一个Action,我用它来测试我的计时操作。但问题是startGettingEmailData
。它使用下一个片段,但它不会触发任何 JSON 请求(我已经通过控制台检查过)。一旦这个问题得到解决,我就可以将 mails
转换为一个动作,这样我就可以在模型中添加电子邮件。
-- url to json
jsonUrl = "https://dl.dropboxusercontent.com/u/14070433/temp.json"
-- get emails
startGettingEmailData: Task Http.Error (List Email)
startGettingEmailData = Http.get emailJsonDecoder jsonUrl
emailJsonDecoder: Json.Decoder (List Email)
emailJsonDecoder =
let makeEmail = Json.object4
(\ti fr da bo -> makeNewEmail -1 ti fr da bo )
("title" := Json.string)
("from" := Json.string)
("date" := Json.string)
("body" := Json.string)
in
"emails" := Json.list makeEmail
我的代码有问题吗?如果没有,那么有没有办法检查 Http.Error 内容? (也许问题不在我的代码,而在网络,但我可以通过浏览器访问保管箱文件...)
您的 checkForNewMails
代码实际上并未对 mails
执行任何操作,因此它永远不会被调用。 let
语句不进行任何调用,它只允许您在更大的函数体内定义一次性函数。由于 in
部分只是 returns TickCounter
,那么这意味着此函数只 returns TickCounter
并且什么都不做。
此外,startGettingEmailData
返回 Task
,这意味着它仅在端口中时被调用。你不能在只有 returns 和 Action
的函数中使用它,因为它永远不会得到 运行.
你会想写一个 port
在定时器上触发,然后创建一个 Task
来轮询你的 url,然后映射那个 GET 请求的响应到一个动作,调用 actions
邮箱。您可以使用 Task.onError
编写一个简单的错误处理程序,它可以通过在您的 Action 类型上创建一个 Error String
构造函数来将错误消息转发到您的视图。
这是一个例子:
getEmailData _ =
let
request =
Http.get emailJsonDecoder jsonUrl
|> Task.map AddEmails
in
request
`Task.onError` (\err -> Task.succeed (Error (toString err)))
`Task.andThen` (\action -> Signal.send actions.address action)
port getEmails : Signal (Task a ())
port getEmails =
Signal.map getEmailData (Time.every (Time.minute / 6.0) )
以上代码将导致 URL 被检索、解析,然后,如果成功,它将触发您的 actions
邮箱并导致视图更新。如果有错误,它将发送 Error
的新动作和一条消息,您应该在视图中处理该消息。 (您必须将 Error String
添加到 Action
联合类型,并在模型、更新和视图函数中处理它。