'Fable: Calling a native Javascript function that requires JQuery
I have F# experience, but am new to Fable (and Javascript, npm, webpack, etc.). In my app, I'm trying to call an external Javascript library called cardsJS in order to display playing cards. However, this library requires JQuery, so I'm not sure how to call it from Fable/F#.
To be specific, one of the Javascript functions exposed by the library is:
// Gets the ID of the card, e.g. "KS" for the king of spades.
cid: function (card) {
var s = card.attr('src');
return s.substring(s.length - 6, s.length - 4);
},
In cardsJS, a card is just an HTML img element, so I tried to import the cid function in my Fable code via:
type ICardsJS =
abstract member cid : HTMLImageElement -> string
let iCardsJS : ICardsJS = importDefault "cardsJS/cards.js"
However, when I call iCardsJS.cid(card) this way, I get a Javascript runtime error:
Uncaught TypeError: card.attr is not a function
at Object.cid (cards.js:30:26)
The problem here is that the library apparently expects a JQuery object, rather than the raw DOM element, so it can call the object's attr function. So I guess my F# interface should actually look something like this instead:
type ICardsJS =
abstract member cid : JQueryThing??? -> string
If I was writing in raw Javascript, I could wrap the DOM element as a JQuery object, like this: $(card). How can I accomplish the same thing in Fable? I'm sure I need to import JQuery into my F# code somehow, but I don't know the right incantation. The only lead I've found so far is this issue, which suggests something like:
let jq : obj = importDefault "jquery"
let jqCard = jq $ card
But that doesn't compile in Fable 3:
error FSHARP: Value restriction. The value 'jqCard' has been inferred to have generic type
val jqCard : obj
I think the problem there is that jq has the wrong type (obj instead of some sort of IJQuery interface) and the compiler thinks that $ is from Fable.Core.JsInterop:
///<summary>
/// Destructure and apply a tuple to an arbitrary value.
/// E.g. `myFn $ (arg1, arg2)` in JS becomes `myFn(arg1, arg2)`
///</summary>
val ($) : callee: obj -> args: obj -> 'a
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
