1

Is JSON parsing possible into a type data or any other form where I can access each individual item within F# using built-in Microsoft provided library?

Following is an output generated by the following code.

"{"account_type":"type1","address":"US","preferred_languages":["en","ar","cn"],"displayName":"John","last_name":"Doe"}"

type Token = {access_token: string; refresh_token: string}

type Authentication =
    new() = {}
    static member token = null;

member this.RequestToken(credentials) =
    let url = "example.com"
    let request = WebRequest.Create(url) :?> HttpWebRequest
    request.Method <- "POST"
    request.ContentLength <- (int64)data.Length

    use requestStream = request.GetRequestStream() 
    requestStream.Write(data, 0, (data.Length))
    requestStream.Flush()
    requestStream.Close()

    let response = request.GetResponse() :?> HttpWebResponse

    use reader = new StreamReader(response.GetResponseStream())
    let output = reader.ReadToEnd()

    reader.Close()
    response.Close()
    request.Abort()

    Authentication.token = JsonConvert.DeserializeObject<Token>(output)
    // the value or constructor "Token" is not defined

Preferably in a type, for instance

type Token = {access_token: string; refresh_token: string}

Edit

Attempting using JSON.net

App2015
  • 973
  • 1
  • 7
  • 19
  • Built-in library - no. The gold standard for this is [JSON.NET](https://www.newtonsoft.com/json). – Fyodor Soikin Mar 08 '18 at 17:57
  • ok, I'll try and also noticed an example there, will come back if I'm stuck. – App2015 Mar 08 '18 at 17:59
  • @FyodorSoikin I've attempted using JSON.NET I installed the module and got it working, the problem is with setting static member of the class, `static member token`. How can I set the JSON parsed result to the static member of the class – App2015 Mar 08 '18 at 18:17
  • `null` is not a valid value for type `Token`. F# doesn't allow nulls for native F# types. Nulls are only there in order to interop with .NET. – Fyodor Soikin Mar 08 '18 at 18:18
  • ok, is there a concept of class static members so other classes can access it's value, basically I want to have this line work `Authentication.token = JsonConvert.DeserializeObject(output)` – App2015 Mar 08 '18 at 18:25
  • This is not how you "assign" a value. In F# mutable variables/fields are modified with the destructive update operator `<-`. Also, you need to make the property read/write, not readonly. Also, you probably want to rethink your architecture to avoid mutation in the first place. – Fyodor Soikin Mar 08 '18 at 18:51
  • You seem to be struggling with the very basics of F#. I recommend first going through a few introductions or tutorials and reading some instructional material to familiarize yourself with the language. The resource I always recommend is https://fsharpforfunandprofit.com/, it's very accessible, yet deep. – Fyodor Soikin Mar 08 '18 at 18:53

1 Answers1

3

You will need to use an external library of some kind. If you want to get the most out of F#, you can solve this very nicely using the F# Data JSON type provider.

The type provider can infer type of JSON data from a sample, so you could parse the above data by using your sample response to guide the inference and then use the inferred type to parse more data:

open FSharp.Data

// Define a type using a sample JSON
type Account = JsonProvider<"""
  { "account_type":"type1","address":"US",
    "preferred_languages":["en","ar","cn"],
    "displayName":"John","last_name":"Doe"}""">

// Now, parse actual data you loaded from somewhere
let parsed = Account.Parse(data)

// Access all the members using a member generated by the type provider.
parsed.AccountType
parsed.Address
parsed.PreferredLanguages |> Seq.length
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • Thanks Tomas, glad to have you, I followed a lot of your videos :) Actually just now I edited my question and I used JSON.net as per the suggestion in the comments and ran into problem when I'm trying to set a static member of the class with the token. See the edited please – App2015 Mar 08 '18 at 18:14
  • basically now how can I set the parsed JSON to the static member of the class? Please keep your answer as I can refer to it when using `FSharp.Data package`. The idea is I can store token as a static member of the class so other classes can access this member – App2015 Mar 08 '18 at 18:18
  • @App2015 Sorry, I'm not sure how to do what you want using JSON.NET. It might make sense to post a new question, ideally with a minimal reproducible example of the problem, asking specifically about how to do this with JSON.NET. – Tomas Petricek Mar 08 '18 at 22:33
  • sure, I'll do that, I'm going through your training at plural sight, which I did once before, and I think you mentioned something like having a database connection that one class retrieves and caches for later use, and then other classes can share this database connection, any example on this? I'm going through tutorial again to find that piece. – App2015 Mar 08 '18 at 23:07
  • Hi Tomas, I posted another question and finally got to the piece where you are passing connection object to the other actors of the system for reuse. I'm trying to do the same with F# for web services. Really need your input on this one please. https://stackoverflow.com/questions/49186245/token-access-reuse-and-auto-refresh-within-the-sdk – App2015 Mar 09 '18 at 03:44
  • P.S. I liked JsonProvider from your world bank examples, practicing to incorporate in my code. – App2015 Mar 09 '18 at 03:54