-
Notifications
You must be signed in to change notification settings - Fork 29
fix: allow passing kit functions by reference #49
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
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.tsfile in my own project with:And I then use this in my app:
Today, the
signAndSendwill throw a runtime error:This is because JavaScript's default behavior is coo coo bananas, no one
understands it, and
thisends up getting bound toundefinedif you use theasync methodName() {…}syntax and then passmethodNameas a reference theway I did.
Today, in order to make my code work, I would need to export the whole
kitandthen change my
signAndSendline 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
kitadds 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.