question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ref<'T>.Value should be an option type

See original GitHub issue

Problem: Forgetting to set your Reference, but using it throws an Exception.

Example:

comp<MatButton> [ attr.ref button; on.click (fun _ -> menu.Value.OpenAsync(button.Value.Ref)) ][  ]
comp<MatMenu> [ attr.ref menu ][]

Forgetting to set attr.ref menu gives a NullReferenceException. Forgetting to set attr.ref button gives “Uncaught (in promise)” (probably because of a NullReferenceException)

Sollution: Currently to avoid this you would have to check for null. The functional approach would be to use an option type. I made this workaround to accomplish this:

type RefOpt<'T>() =
    inherit Ref<'T option>()

    member val Value = None with get, set
    
    override this.Render(builder, sequence) =
        builder.AddComponentReferenceCapture(sequence, fun v ->
            this.Value <-
                match v with
                | :? 'T as result -> Some (result)
                | _ -> None)
        sequence + 1

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Tarmilcommented, Feb 18, 2021

Or use tryUnbox 😉

1reaction
Tarmilcommented, Feb 14, 2021

So I’ve been thinking about this a bit. I still don’t quite like the boilerplate you’re adding in your specific example, especially considering that it’s simplified because it ignores the return value of the OpenAsync method. Across an application you might end up needing a whole set of these combinators, depending on the number of refs, the sync/async result, etc.

But then I realized that it would be made nicer and more consistent by adhering more closely to MVU, and moving the call to a command:

type Message =
    | OpenMenu of menu: MatMenu option * button: MatButton option
    | OpenedMenu
    | Error of exn

let update message model =
    match message with
    | OpenMenu (Some menu, Some button) ->
        model, Cmd.OfTask.either menu.OpenAsync button (fun () -> OpenedMenu) Error
    | OpenMenu _ ->
        model, Cmd.ofMsg (Error (exn "You forgot to set a reference!"))
    | OpenedMenu ->
        model, Cmd.none // If OpenAsync had a Task<_> result, you could process it here
    // ...

type MyComponent() =
    inherit ElmishComponent<Model, Message>()

    let menu = Ref<MatMenu>()
    let button = Ref<MatButton>()

    override this.View model dispatch =
        concat [
            comp<MatButton> [ attr.ref button; on.click (fun _ -> dispatch (OpenMenu (menu.Value, button.Value))) ] []
            comp<MatMenu> [ attr.ref menu ][]
        ]
Read more comments on GitHub >

github_iconTop Results From Across the Web

Editing Advanced Settings for supports in PreForm
Use Advanced Settings in PreForm to gain greater control over the amount, size, type, and height of supports generated.
Read more >
How do I borrow a reference to what is inside an Option<T>?
First of all, you don't need &mut self . When matching, you should match e as a reference. You are trying to return...
Read more >
UltiMaker Cura - Build plate adhesion settings
There are three types of build plate adhesion: Skirt, Brim, and Raft. You can also easily disable the adhesion types by selecting None....
Read more >
TiKV Configuration File
Specifies the engine type. This configuration can only be specified when creating a new cluster and cannot be modifies once being specified.
Read more >
Integrated Storage (Raft) backend - Vault
The Integrated Storage (Raft) backend is used to persist Vault's data. Unlike all the other storage backends, this backend does not operate from...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found