Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonProvider - writable properties? #1465

Open
JordanMarr opened this issue Sep 2, 2022 · 1 comment
Open

JsonProvider - writable properties? #1465

JordanMarr opened this issue Sep 2, 2022 · 1 comment

Comments

@JordanMarr
Copy link

Is it possible for the JsonProvider to generate types with writable properties?

My use case is that I have a rather large JSON sample object that I want to create a new instance of using the default values in my sample and then manually modify only a few select fields. However, the read-only nature of the generated properties prevents me from using this technique, leaving only the option of initializing every value via the constructor.

@JordanMarr
Copy link
Author

I came up with the following workaround to allow editing individual fields:

Set Value Extension Methods

module Extensions

open FSharp.Data
open FSharp.Data.JsonExtensions

/// Extension methods to allow overwriting read-only properties on generated types.
type JsonValue with 

    member private this.SetValue(jsonProperty: string, value: JsonValue) = 
        let idx = this.Properties |> Array.findIndex (fun (pNm, _) -> pNm = jsonProperty)
        this.Properties[idx] <- jsonProperty, value

    /// Sets a json property on a generated type.
    member this.Set(jsonProperty: string, value: JsonValue) = 
        this.SetValue(jsonProperty, value)

    /// Sets a json property on a generated type.
    member this.Set(jsonProperty: string, value: string) = 
        this.SetValue(jsonProperty, JsonValue.String value)
            
    /// Sets a json property on a generated type.
    member this.Set(jsonProperty: string, value: decimal) = 
        this.SetValue(jsonProperty, JsonValue.Number value)

    /// Sets a json property on a generated type.
    member this.Set(jsonProperty: string, value: float) = 
        this.SetValue(jsonProperty, JsonValue.Float value)

    /// Sets a json property on a generated type.
    member this.Set(jsonProperty: string, value: bool) = 
        this.SetValue(jsonProperty, JsonValue.Boolean value)

Usage

[<Test>]
let ``Create RFI Entity`` () = 
    let rfi = RfiTypes.GetSample()
    rfi.Subject =! "Wall Color"
    
    // manually overwrite a read-only property value
    rfi.JsonValue.Set("subject", "New Subject")
    
    rfi.Subject =! "New Subject"

It's not perfect as I lose some of the benefits of having strongly typed entities; however, it still saves me from having to manually generate large entities, and since I only need to edit a handful of properties, it seems like a pretty good workaround.

It would be a lot more strongly typed if there was an option of having writable properties though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant