Pass a named function callback to an old JS library
I have a library that accepts a
data-callback="someFn"
attribute in one of the elements. Is there a way in SolidJS to create this function at the component level and pass it down to that attribute?49 Replies
data-callback="someFn"
is just a simple attribute which can't hold anything except strings, so that library must have some way of defining a function with that name e.g. lib.registerCallback('someFn', () => {})
Not really, as most old JS libraries do, the
someFn
is expected to exist in the global JS scope.some way of defining a function with that namethat was provided as an example but the point still stands and i'm not sure what the question really is then because that depends entirely on the library this is valid in soild as it is
data-callback="someFn"
The question is how to define a global scope JS function that can be called like that and still only exist at the component level.
ChatGPT gave me this as starting point:
The question is how to define a global scope JS function that can be called like that and still only exist at the component level.that is a contradiction
:Worry_Think:
window.fn = ...
:ryanshades:
I actually use this with XLSX lib
It needs to temporarily exist in the global scope as long as the component is on the page. Once it's unmounted it can be removed. No contradiction 😅
you could do something like your snippet, but you will have to do some type of reference counting too (because if you have 2 of those components and 1 cleans up you don't want that global function to be undefined suddenly)
Since vite doesn't know how to bundle XLSX, and end up with bloated js
External script is even lighter
and you will have to be careful not to have conflicts too
Yeah I can just generate a random hash to append to the that global fn name. That's not an issue.
what is that library you've spoken of anyway?
Not gonna mention the library because I already know people will freak out about the fact that there are alternatives for that library in solid but then I have to explain how they don't fit my needs. 😬
:confusednick:
maybe what if you would add it to the dom-element's 'callback'-property and do
this.callback
?yeah, something like that
it's google sign in
i'm not sure how this came off. did you really experience this here?
But what's the goal tho, I've never needed something similar to this
data-callback
I've been around forums and survived on SO for 17 years. That built up that assumption.
:_Worry_Universe:
This is much nicer community than I've ever experienced so I'm kinda thrown off by that
ye it's cozy here!
and people up for cursed experiments
but to circle back to your question: i think this is valid way of doing it
I thought I had it but now no errors and no components show up 😂
and then:
Is my currently "not working" solution
mb
<script src="https://accounts.google.com/gsi/client" async defer></script>
?
not sure if that would work:Worry_Think:
Yeah it stopped working as soon as I wrapped the component in a
clientOnly
But that's required for accessing window
no?i think
onMount
will not run on server
all effects run on client afaikMaybe I should try this: https://www.npmjs.com/package/google-oauth-gsi?activeTab=readme
npm
google-oauth-gsi
A user-friendly API for GIS SDK, using the new Google Identity Services SDK 🚀. Latest version: 4.0.1, last published: 9 months ago. Start using google-oauth-gsi in your project by running
npm i google-oauth-gsi
. There are no other projects in the npm registry using google-oauth-gsi.Although 800 downloads is low 😅
:Worry_Think:
Or maybe it's high considering only insane people would do this
removing
clientOnly
didn't work?Moving the
script
outside didn't work. I can try removing clientOnly entirely, let's see...How do Google packages work under the hood? They make an abstraction layer and fire an API call for it?
:Worry_Think:
Yeah no, it doesn't work without
clientOnly
. The dev server just exists with this errorWeird that it errors out on the unmount
move the onCleanup in onMount?
You mean like this:
?
yup
Ok seems to work as the one tap login thing appears
But then I'm back to "The value of 'callback' is not a function. Configuration ignored."
you can also do
if (!isServer) { ... }
instead of onMount
I think I know what's up
The imported script is run before the
onMount
Maybe if I create the script tag in the onMount
that's betterif it's a component you will only use in your own project you could also just yolo it and do
Yeah that seems to work
I keep forgetting that in solid there's no restriction to be in a component to do most things
Like I'm assuming I can call an async solid start function like
const authenticateWithGoogle = action(async () => { ... })
outside of a component, right?not 100% sure myself
not a solid start expert
usually, no
but you can turn it into one using
useAction
inside a component which must be inside a route context
so, yes 😆Thank you all very much ❤️
you are very welcome!