@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
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
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
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
}
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
}
command.input <- { new DescribeInstancesCommandInput with member _.Filters = [] and _.DryRun = false } ???
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
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
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 |}
the type '{| bar: 'a; baz: 'b; foo: 'c |}' does not support the operator '!!
Since fable-compiler 2.3.6, when using the dynamic cast operator
means, if fable-compiler in npm or nuget
If one day you need !!
it is available under open Fable.Core.JsInterop
.
The cleanest way of creating POJO is with jsOptions
and createEmpty
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
Yes, it does in general I use the Web interface.
But, you still need to know what you do because it does like 90% of the work and you need some tweaking in general
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.
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