Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Leo Lorenzo Luis
    @leolorenzoluis
    I suppose I can check which Cmd.OfAsync to perform depending on what is the current selected url is..?
    Maxime Mangel
    @MangelMaxime

    @leolorenzoluis For the refresh, you can use any of the solution you listed.

    It depends on what you system need does it really need to data update instantly? Then a periodic pull is probably enough but it could also trigger more network traffic.

    If you need real time data, in general web sockets or other subscription methods are best as the server can notify the client each time a change is needed. Same goes for server side event

    Leo Lorenzo Luis
    @leolorenzoluis
    Awesome. Is it feasible to do Fable with AWS Lambda with AWS npm instead of .net module? Are there any examples of that
    Maxime Mangel
    @MangelMaxime
    What do you mean by "instead" of .net module ?
    Leo Lorenzo Luis
    @leolorenzoluis
    I want to write lambda code using Fable with AWS javascript package instead of .NET. I believe it's much easier to interface in the js world than .NET since I have to transform the values in .NET to native list/seq.
    Maxime Mangel
    @MangelMaxime
    Fable can use any JavaScript API, you just need to create the binding for it if you want the type safety.
    Leo Lorenzo Luis
    @leolorenzoluis
    Trying to open a new fresh Fable from template with Rider but it doesn't seem to work properly in Rider. What am I missing? Is it similar to fable-compiler/Fable#1151
    Maxime Mangel
    @MangelMaxime
    Does it works in VSCode?
    Does the project build/restore?
    Leo Lorenzo Luis
    @leolorenzoluis
    Yes, it looks like I had to change the rider to open the correct directory instead. The ui was confusing. It's working now. :)
    Screen Shot 2022-05-17 at 12.15.24 PM.png
    Leo Lorenzo Luis
    @leolorenzoluis
    Is this still the correct way to create a Fable NodeJS project? https://github.com/fable-compiler/fable3-samples/tree/main/nodejsbundle npm package is pointed to Fable 2.x.x
    aka is the fable npm package should still be used?
    Leo Lorenzo Luis
    @leolorenzoluis
    Am I doing this right? Trying to use Fable to call AWS npm package. I'm not sure how to translate new objects and async await
    module App     
    open Fable.Core
    
    type DescribeInstanceCommand =
        abstract blah: unit
    and EC2Client =
        [<Emit("new $0($1)")>]
        abstract send: obj -> obj
    
    [<Import("EC2Client","@aws-sdk/client-ec2")>]
    let ec2: EC2Client = jsNative
    let command = {||}
    let a = ec2.send(command)
    printfn $"%A{a}"
    For reference of the javascript https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-ec2/classes/describeinstancescommand.html
    Leo Lorenzo Luis
    @leolorenzoluis
    Second attempt. Please give feedback as I'm still learning...
    
    module App     
    open Fable.Core
    open Fable.SimpleJson
    
    type EC2Config =
        abstract runtime: string
    
    type Instance =
        abstract AmiLaunchIndex: int
        abstract InstanceId: string
        abstract ImageId: string
    
    type Reservation =
        abstract Groups: ResizeArray<obj>
        abstract Instances: ResizeArray<Instance>
    
    type Filter =
        abstract Name: string
        abstract Values: ResizeArray<string>
    
    type DescribeInstancesCommandInput =
    //    abstract DryRun: bool
        abstract Filters: Filter list
    
    type DescribeInstancesCommandOutput =
        abstract Reservations: ResizeArray<Reservation>
        abstract NextToken: string
    
    type DescribeInstanceCommand =
        abstract input: DescribeInstancesCommandInput with get, set
        [<Emit("new $0()")>]
        abstract Create: unit -> DescribeInstanceCommand
    
    and EC2Client =
    //    [<Emit("new $0($1)")>]
        abstract send: DescribeInstanceCommand -> DescribeInstancesCommandOutput
        [<Emit("new $0()")>]
        abstract Create: EC2Config -> EC2Client
    
    [<Import("EC2Client","@aws-sdk/client-ec2")>]
    let ec2: EC2Client = jsNative
    
    [<Import("DescribeInstancesCommand","@aws-sdk/client-ec2")>]
    let describeInstancesCommand: DescribeInstanceCommand = jsNative
    
    let outputPromise = promise {
    //let command =  { new DescribeInstancesCommandInput with member _.DryRun = false  }
        let command = describeInstancesCommand.Create()
        command.input <- { new DescribeInstancesCommandInput with member _.Filters = [] } 
        let test = ec2.Create({ new EC2Config with member _.runtime = "" })
        let a = test.send(command)
        return a
    }
    outputPromise.``then``(fun x ->
        let blah = x.Reservations
                   |> Seq.collect (fun y ->y.Instances)
        blah |> Seq.iter(fun z -> printfn $"{SimpleJson.stringify(z)}")) |> ignore
    Enrique Ramirez
    @enriquein
    I thought you could use async {} or Async as you normally would in F#, and Fable would handle the promise parts of it properly. I could be wrong, never done nodejs via Fable but it's something I'd like to try in the future.
    Maxime Mangel
    @MangelMaxime

    async in Fable are a custom implementation because this is not native to Node.js

    What is native to Node.js is Promise. This is confusing because in Node.js they kind of used async & wait keyword when it is in fact about promise.

    To use Promise in Fable, it is recommanded to use Fable.Promise which offers some good API on top of it like:

    promise {
        let! res1 = LongRunningOpetation () // Waiting for the result
        let! result2 = SecondOperation res2 // Second operation which use the result of the first one
    
        return result2.Code
    }
    Leo Lorenzo Luis
    @leolorenzoluis
    is my way of typing the aws sdk correct though? I'm only partially guessing until I see the generated js code to look like the same as what the official docs would do...
    This is my 3rd attempt refactoring to get rid of the then
    
    type DescribeInstanceCommand =
        abstract input: DescribeInstancesCommandInput with get, set
        [<Emit("new $0()")>]
        abstract Create: unit -> DescribeInstanceCommand
    
    and EC2Client =
    //    [<Emit("new $0($1)")>]
        abstract send: DescribeInstanceCommand -> Promise<DescribeInstancesCommandOutput>
        [<Emit("new $0()")>]
        abstract Create: EC2Config -> EC2Client
    
    [<Import("EC2Client","@aws-sdk/client-ec2")>]
    let ec2: EC2Client = jsNative
    
    [<Import("DescribeInstancesCommand","@aws-sdk/client-ec2")>]
    let describeInstancesCommand: DescribeInstanceCommand = jsNative
    
    let outputPromise = promise {
    //let command =  { new DescribeInstancesCommandInput with member _.DryRun = false  }
        let command = describeInstancesCommand.Create()
        command.input <- { new DescribeInstancesCommandInput with member _.Filters = [] } 
        let test = ec2.Create({ new EC2Config with member _.runtime = "" })
        let! a = test.send(command)
    
        a.Reservations
        |> Seq.collect (fun y ->y.Instances)
        |> Seq.iter(fun z -> printfn $"{SimpleJson.stringify(z)}")
    
        return a
    }
    I'm not really sure if I'm doing it right with creating objects with emit attribute, and I don't know how to declare more than 1 property like..
    command.input <- { new DescribeInstancesCommandInput with member _.Filters = [] and _.DryRun = false } ???
    Maxime Mangel
    @MangelMaxime

    It seems ok yes.

    Writing binding is not easy to do, there is a lot of trial and error when starting until you find the right tricks / types and know what Fable generate when you do what.

    I'm only partially guessing until I see the generated js code to look like the same as what the official docs would do

    Yep, that's how I do it. And once, I have a small portion working in general it is just a matter of copy/paste because the library use similar API often

    Leo Lorenzo Luis
    @leolorenzoluis
    so as a rule of thumb when a js library has a new SomethingObject() when writing typings, then I have to create a function in the given type to return that instance?
    Maxime Mangel
    @MangelMaxime

    About the creation of your command, you are probably doing it wrong. Because that kind of syntax doesn't exist in JavaScript.

    If the API is expecting a POJO you should look at Fable documentation about that:

    https://fable.io/docs/communicate/js-from-fable.html#plain-old-javascript-objects

    You should also try to look for existing documentation/blog post about how to create a binding.

    This one is good in general: https://medium.com/@zaid.naom/f-interop-with-javascript-in-fable-the-complete-guide-ccc5b896a59f

    It is a bit old but the tricks shown in it still work i think

    Leo Lorenzo Luis
    @leolorenzoluis

    Awesome thank you.

    I'm trying the sample but it doesn't recognize the !! maybe it's only for non nodejs?

    type IMyInterface =
        abstract foo: string with get, set
        abstract bar: float with get, set
        abstract baz: int option with get, set
    // Warning, "foo" must be a string
    let x: IMyInterface = !!{| foo = 5; bar = 4.; baz = Some 0 |}
    I get the type '{| bar: 'a; baz: 'b; foo: 'c |}' does not support the operator '!!
    Not sure what Since fable-compiler 2.3.6, when using the dynamic cast operator means, if fable-compiler in npm or nuget
    Maxime Mangel
    @MangelMaxime
    I really should put a HUGE warning on the !! example that's the worst way of doing it because it is not typed.

    If one day you need !! it is available under open Fable.Core.JsInterop.

    The cleanest way of creating POJO is with jsOptions and createEmpty

    Leo Lorenzo Luis
    @leolorenzoluis

    Ok for function/constructors that are expecting an object createEmpty is way to go. However, for libraries that I need to import that requires to be instantiated import { EC2Client, DescribeInstanceCommand } from '@aws-sdk/client-ec2 then creating a Create function on the type bindings that returns itself is the way to go?

    Javascript:

    import { EC2Client, DescribeInstancesCommand } from '@aws-sdk/client-ec2'
    let ec2Client = new EC2Client();
    let describeInstanceCommand = new DescribeInstancesCommand();

    Fable:

    type DescribeInstanceCommand =
        abstract input: DescribeInstancesCommandInput with get, set
        [<Emit("new $0()")>]
        abstract Create: unit -> DescribeInstanceCommand
    
    and EC2Client =
        abstract send: DescribeInstanceCommand -> Promise<DescribeInstancesCommandOutput>
        [<Emit("new $0()")>]
        abstract Create: EC2Config -> EC2Client
    Maxime Mangel
    @MangelMaxime
    If you need to call a constructor yes
    Leo Lorenzo Luis
    @leolorenzoluis
    Does ts2fable lib works?
    Maxime Mangel
    @MangelMaxime

    Yes, it does in general I use the Web interface.

    https://fable.io/ts2fable/

    But, you still need to know what you do because it does like 90% of the work and you need some tweaking in general

    Leo Lorenzo Luis
    @leolorenzoluis
    That article was really helpful. Should've been part of the official docs https://fable.io/docs/communicate/js-from-fable.html
    Leo Lorenzo Luis
    @leolorenzoluis
    Just saw Fable.Lit. When should I use that?
    Maxime Mangel
    @MangelMaxime

    Fable.Lit is an equivalent to React so it is to build client application.

    Then it is a matter of preference is you prefer working with standard API from the browser aka "custom element" or use React and the huge ecosystem already in place.
    It is also possible to mix both, to know more you should read about it in the JavaScript world.

    Leo Lorenzo Luis
    @leolorenzoluis
    Thanks Maxime. Fable looks like transpiling code to Rust/Python too does it use similar AST libs like babel for those languages?
    Maxime Mangel
    @MangelMaxime

    Fable doesn't use babel anymore for the transpilation.

    So no, it just output the languages directly.

    Leo Lorenzo Luis
    @leolorenzoluis
    What does it do now or how?
    Maxime Mangel
    @MangelMaxime

    Well, it write to the text file as a human would do.

    If you write let x = 4 in F# it writes export const x = 4; in the generated file.

    It does that, by parsing the F# AST. If you want to know more you will have to read the source code

    Aleksander Spro
    @ProjectEon_gitlab

    Has anyone here tried making Fable bindings for Highmaps (from Highcharts).

    I'm struggling with a runtime error that doesn't make sense. Comparing source to a working Typescript version they look identical to me so I must be missing something...

    https://github.com/projecteon/Fable.Highchart/blob/main/README.md

    Joh Dokler
    @joahim
    @ProjectEon_gitlab What is the error? I have successfully used Highcharts maps from Fable on this project. We do not use types for props (we pass them directly as anonymous records) but you may be able to find out what is wrong in your case from our code:
    https://github.com/sledilnik/website/blob/master/src/visualizations/_highcharts.js#L129
    https://github.com/sledilnik/website/blob/master/src/visualizations/Highcharts.fs#L16
    https://github.com/sledilnik/website/blob/master/src/visualizations/MapChart.fs#L577
    Aleksander Spro
    @ProjectEon_gitlab
    image.png
    By google, most errors are related to charts and them needing an extra package for chart type definitions. But the TS version of this demo works just fine without...
    Aleksander Spro
    @ProjectEon_gitlab
    My types (very dumbed down to my exact needs) seem to map corretly in console logs.. get the feeling its something else causing this error
    Aleksander Spro
    @ProjectEon_gitlab
    @joahim Any reason you went with a pure js file for booting the react component?