0

I get input JSON data from JS. This is a simple object, among which there is a date in the format "DD.MM.YYYY" - just a string.

If there is no dateStart in the object, I have to replace it with the current date (in withDefault).

paramsDecoder : Decode.Decoder Params
paramsDecoer =
    Decode.succeed Params
        |> Decode.andMap (Decode.field "dateStart" (Decode.string) |> (Decode.withDefault) "")
        |> Decode.andMap (Decode.field "dateEnd" (Decode.string)   |> (Decode.withDefault) "")
        |> Decode.andMap (Decode.field "country" (Decode.string)   |> (Decode.withDefault) "spain")

How can I do this in ELM? Timezone is not important and is always equal to the same region.

I found an example of Time.now Time.zone usage, but there time is getting in Update and its too late.

glennsl
  • 28,186
  • 12
  • 57
  • 75
Stefan B
  • 219
  • 1
  • 12
  • Possible duplicate of [How do I get the current time in Elm?](https://stackoverflow.com/questions/29453679/how-do-i-get-the-current-time-in-elm) – glennsl Jan 10 '19 at 15:22
  • It was 0.18 elm in this post. But in my question - 0.19 and this is a big difference. – Stefan B Jan 10 '19 at 15:29
  • What's the big difference? It works exactly the same, except `Time.now` has been moved to a separate package, `elm/time`, as explained in [the guide](https://guide.elm-lang.org/effects/time.html) – glennsl Jan 10 '19 at 15:35
  • There's also an answer covering 0.19 in the duplicate question: https://stackoverflow.com/a/52156804/7943564 – glennsl Jan 10 '19 at 15:39
  • Yes, i saw that post but there time is getting in Update and its too late. – Stefan B Jan 10 '19 at 15:46
  • `update` is the only place it can be received. See [my answer here](https://stackoverflow.com/a/53929209/7943564). Time and random numbers are both side-effects. – glennsl Jan 10 '19 at 15:54
  • 3
    If it's required by `init`, I suggest moving this logic into the JS side and make sure when `dateStart` enters Elm, it's already the value you want. – blurrcat Jan 11 '19 at 04:02
  • Or alternatively pass in a `defaultDate` into init too and use that when no `dateStart` is present. – Richard Huxton Jan 11 '19 at 10:27
  • You can also store it in a model as Value and then decode it when current time arrives. – Karol Samborski Jan 16 '19 at 11:14

1 Answers1

0

I solved this in two parts:

Part 1

Send the current time in to Elm when it initializes, using flags:

Elm.Main.init({flags: Date.now()});

And put it in your model:

import Time exposing (Posix, millisToPosix)

type alias Model = { now : Time.Posix, ... }

init : Int -> (Model, Cmd Msg)
init time = (Model (millisToPosix time), Cmd.none)

For your use case, you can then use withDefault model.now.

Part 2

The solution in Part 1 will only set now to the time when the page is loaded.

If you want to keep an up to date time you can use Time.every to update your model:

import Time exposing (Posix, millisToPosix, every)

timeOutCheck : Sub Msg
timeOutCheck = Time.every 250 UpdateTimeNow

type Msg = UpdateTimeNow Posix | ...

update msg model = case msg of
  UpdateTimeNow time = { model | now = time }
  ...

This will ensure now is never more than 250 ms behind the current time. You can change 250 to suit your need.

davetapley
  • 17,000
  • 12
  • 60
  • 86