-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: allow passing kit functions by reference #49
base: main
Are you sure you want to change the base?
Conversation
I'd love to add a test, but didn't see any existing test files. If I'm being silly, please let me know where the tests are and I'll be sure to add one or two! |
What ---- Define methods using `methodName = async () => {…}` syntax, rather than `async methodName() {…}` Why --- This allows for better APIs when using StellarWalletsKit. For example, given a `stellar-wallets-kit.ts` file in my own project with: ```ts const kit: StellarWalletsKit = new StellarWalletsKit({…}); export const signTransaction = kit.signTransaction; ``` And I then use this in my app: ```ts const tx = await incrementor.increment(); const { result } = await tx.signAndSend({ signTransaction }) ``` Today, the `signAndSend` will throw a runtime error: ``` TypeError: Cannot read properties of undefined (reading 'selectedModule') ``` This is because JavaScript's default behavior is coo coo bananas, no one understands it, and `this` ends up getting bound to `undefined` if you use the `async methodName() {…}` syntax and then pass `methodName` as a reference the way I did. Today, in order to make my code work, I would need to export the whole `kit` and then change my `signAndSend` line to: ```ts const { result } = await tx.signAndSend({ signTransaction: async (xdr) => { return await kit.signTransaction(xdr); }, }); ``` I don't like this because A) it's ugly and B) I don't think it's good practice to export the whole `kit`. Within my app, I want to have the ability to wrap interfaces like `signTransaction`, so that I can always make sure app-specific logic gets taken care of. Exporting all of `kit` adds more room for error. The Fix ------- Using the arrow syntax with `methodName = async (…) => {…}` makes JS use similar `this`-binding logic to every other language, and makes my pass-by-reference use-case possible.
8d9f8e7
to
cfab98e
Compare
Hi there, I think this might not be the best solution because regular classes methods are defined in the prototype of the object while anonymous arrow functions will be duplicated every time someone extends the kit's class and that could have unexpected behaviors if someone uses the kit as a base for another library (tho I don't fully remember at the moment so I might be wrong). Following your example, wouldn't be the same doing this but without changing all the methods in the kit? const kit = new StellarWalletsKit({…});
export const signTransaction = kit.signTransaction.bind(this);
const tx = await incrementor.increment();
const { result } = await tx.signAndSend({ signTransaction }); I haven't used the |
And just make sure it works, in general. It was pretty broken. Relies on these fixes: - stellar/soroban-template-astro#13 - stellar/soroban-template-astro#14 And can be cleaned up once this is merged: - Creit-Tech/Stellar-Wallets-Kit#49
Unfortunately, this doesn't work: const kit = new StellarWalletsKit({…});
export const signTransaction = kit.signTransaction.bind(this); I still get the same error. And you can see why: what is
That may or may not be a good point 😂 Do we think it's more important to make it easy to use the kit as a base for another library, or to make it predictable (and beautiful) to use the kit as-is within apps? |
My bad, I meant |
And just make sure it works, in general. It was pretty broken. Relies on these fixes: - stellar/soroban-template-astro#13 - stellar/soroban-template-astro#14 And can be cleaned up once this is merged: - Creit-Tech/Stellar-Wallets-Kit#49
And just make sure it works, in general. It was pretty broken. Relies on these fixes: - stellar/soroban-template-astro#13 - stellar/soroban-template-astro#14 And can be cleaned up once this is merged: - Creit-Tech/Stellar-Wallets-Kit#49
Yes, I still find it a little clumsy and error-prone. To me, this sort of thing seems like the main use-case. I'm not sure it's worth requiring these |
And just make sure it works, in general. It was pretty broken. Relies on these fixes: - stellar/soroban-template-astro#13 - stellar/soroban-template-astro#14 And can be cleaned up once this is merged: - Creit-Tech/Stellar-Wallets-Kit#49
And just make sure it works, in general. It was pretty broken. Relies on these fixes: - stellar/soroban-template-astro#13 - stellar/soroban-template-astro#14 And can be cleaned up once this is merged: - Creit-Tech/Stellar-Wallets-Kit#49
What
Define methods using
methodName = async () => {…}
syntax, rather thanasync methodName() {…}
Why
This allows for better APIs when using StellarWalletsKit. For example, given a
stellar-wallets-kit.ts
file in my own project with:And I then use this in my app:
Today, the
signAndSend
will throw a runtime error:This is because JavaScript's default behavior is coo coo bananas, no one
understands it, and
this
ends up getting bound toundefined
if you use theasync methodName() {…}
syntax and then passmethodName
as a reference theway I did.
Today, in order to make my code work, I would need to export the whole
kit
andthen change my
signAndSend
line to:I don't like this because A) it's ugly and B) I don't think it's good practice
to export the whole
kit
. Within my app, I want to have the ability to wrapinterfaces like
signTransaction
, so that I can always make sure app-specificlogic gets taken care of. Exporting all of
kit
adds more room for error.The Fix
Using the arrow syntax with
methodName = async (…) => {…}
makes JS use similarthis
-binding logic to every other language, and makes my pass-by-referenceuse-case possible.