Closed Garito closed 2 years ago
You should not have the last () since it would invoke the unsubscribe function (subscribe returns it) immediately after subscription.
Sorry, I've tried this:
let cData;
const customChain = makeChainStore('xDai');
const unsubscribe = customChain.chainData.subscribe(c => cData = c);
console.log(cData);
unsubscribe();
with the same result
PS: would be nice if you don't close the issue before being sure it is resolved
Hum. I really though it was the reason. Anyway, there is no problem to reopen an issue if you want ...
I tried a similar code as yours inside svelte-web3/examples/svelte-app-template-web3
and i cannot reproduce your bug. could you try the same patch :
diff --git a/examples/svelte-app-template-web3/src/RPC.svelte b/examples/svelte-a>
index f8031f1..7076691 100644
--- a/examples/svelte-app-template-web3/src/RPC.svelte
+++ b/examples/svelte-app-template-web3/src/RPC.svelte
@@ -9,6 +9,12 @@
ethStore.setProvider(provider)
+ let cData
+ chainData.subscribe(c => {
+ console.log('store has been updated', c)
+ cData = c
+ })
+
</script>
<div class="card">
@@ -23,6 +29,9 @@
<p>
chainData = {JSON.stringify($chainData)}
</p>
+ <p>
+ cData = {JSON.stringify(cData)}
+ </p>
{/if}
</div>
</div>
Sorry, I've tried this:
let cData; const customChain = makeChainStore('xDai'); const unsubscribe = customChain.chainData.subscribe(c => cData = c); console.log(cData); unsubscribe();
with the same result
PS: would be nice if you don't close the issue before being sure it is resolved
This second example by the way will follow the same workflow has the first since you will unsubscribe before the state of the store changes and the subscribe handler get called.
I don't know if your test makes sense in my case cause my code runs in a store
About my 2nd example: when should I unsubscribe from your store? I'm using the same pattern with other stores without any problem
I don't know if your test makes sense in my case cause my code runs in a store
About my 2nd example: when should I unsubscribe from your store? I'm using the same pattern with other stores without any problem
I don't know since it all depends a global context I know nothing of. It just means that when you subscribe with the handler c => cData = c
, chainData
state (aka c
) is still undefined
. Which is quite logical because I don't see a customChain.setProvider(<provider>)
before the console.log and the unsubscribe.
Not so obvious, should specify this in the docs? Besides, some info is already there before connect (or should be) Ex: chainData, my case Meanwhile I've tried this:
let cData;
const customChain = makeChainStore('xDai');
customChain.setProvider('https://rpc.xdaichain.com/');
const unsubscribe = customChain.chainData.subscribe(c => cData = c);
console.log(cData);
unsubscribe();
no luck either I guess it is a matter of how the info it is instantiated?
I've tried without unsubscribe and eventually the info shows up It is possible that some stores don't wait the provider? chains.json is already there Or how to wait for the info to be loaded?
Yes, the setProvider is async so the lines after setProvider get executed before the state has changed. I'll review the doc to make this more clear. There is no easy way to wait outside of your handler but you might consider just making the logic that needs the chain inside the handler like :
customChain.chainData.subscribe(c => {
if (c) {
<your logic here>
unsubscribe()
}
});
I rather prefer if this library fills up the stores that aren't dependent from the provider which will solve this issue and will work in a more logical way, don't you think?
In my case it is difficult to do it without breaking the logic of what is happening in my code
How hard will be to make this change?
I'm not sure to understand what you suggest. There is always a need for a provider to use web3 (except the utils part). If you want to use the raw data information from src/chains.js
, you may want to use that file directly without creating a store.
To be more precise, 'xDai' is just an id here, not a key to fetch xDai information.
can you load this info in chainData without the provider? chainId... those stores? The point is that make total sense and will be more usable in more cases... Should not be super hard to do?
no because the name 'xDai' doesn't imply the provider will be necessarily dai. But i can make an accessor for information in chains.js
outside of stores
but the chains.json info will not be different, isn't it? I mean if you choose xDai as network no matter if the provider is set or not that the chain info can be known and the chain id etc if you choose network 3 (ropsten) the chainData and the chainId can be setted without the provider
oups, forgot to answer that. No data returned would be different depending on the provider selected. In the case of xDai, it would be
{
name: 'xDAI Chain',
chain: 'XDAI',
network: 'mainnet',
...
}
In the case of ropsten
{
name: 'Ethereum Testnet Ropsten',
chain: 'ETH',
network: 'ropsten',
...
}
I added a getter allChainsData
to last release 2.3.1 and rewrote the README to make clear that chainData
return undefined if not connected.
Thanks for that
About the issue: I think you are confusing provider with network. Let's try to be in the same page: Network is
Provider is determined by the rpc url
The network data is already in the chains.json the moment you choose the network The provider for that network it is only available after the connection
Which should mean that makeChainStore can fill part of the stores it provides (example chainData) before the provider is connected
I think i know the difference :)
In your opinion, & how makeChainStore
would know which network is going to be connected before setProvider
?
chains.filter(chain => chain.chainId === chainId)?
We don't know chainId before setProvider
oh god... chains.filter(chain => chain.rpc.includes(providerUrl))
I'm not asking for some js lesson. Please try to be less condescending and try to understand what i'm saying during this whole thread. makeChainStore
creates an Object of empty stores. There is no indication on which chain/network is going to be used before you invoke setProvider
.
I'm not condescending, I'm amazed you don't get the point (seems to me really obvious, so sorry if it is not so for you and I'm being harsh with you, understand that I can interpret your responses as if you are tolling me, it is not the first time we don't understand each other)
The makeChainStore needs an information that it is included in the chains.json which make a transitive relation between the provider and the chain info
Checking your code, it is a matter of when you initialize the bunch of stores makeChainStore returns chainData, chainId and this kind of information can be filled before the provider is set and, when you want to interact with the network, then set the provider and fill web3, selectedAccount and so on
I get your point since the start. I just trying to explain you why your are wrong. The function works this way:
({ web3, connected, selectedAccount, chainId, chainData, ...ethStore } = makeChainStore('<id>'))
ethStore.setProvider('https://rpc.slock.it/goerli')
<id>
can be goerli
, 'XXX', infura
, another-cool-id
or xDai
. In all cases, the chainData
store will be set when we know about the chain (through the fact that a provider is set). In the example above, it will be goerli chainData
in all cases. Again, you can't guess which which chain is going to be used, so no early initialization of chainData
should happen.
what is the point of chains.json, then?
You mean chains.js
? initializing chainData when it gets possible. If you want to use the whole list, you can use the new getter added in release 2.3.1.
chains.js === https://chainid.network/chains.json Quote: initializing chainData when it gets possible
are you trolling me?
reread the thread paying more attention to
" To be more precise, 'xDai' is just an id here, not a key to fetch xDai information."
"no because the name 'xDai' doesn't imply the provider will be necessarily dai. "
"
Yeah, me neither I think that you are the one that should reread the threat Your attitude kills a lot of help for this library
Here is my code:
cData is always empty dict Any idea why? Thanks