gun
gun copied to clipboard
Referencing nodes that hold only primitive values
Edit 02:
Okay. I suppose the problem here is that because a new node is not created when doing:
const info = gun.get("foo").get("info").put("fido");
this is essentially the same thing as doing:
const info = gun.get("foo").get("info");
.
Then when referencing the thing node, .on will only be called if thing actually gets a value.
const info = gun.get("foo").get("element");
gun.get("foo").get("pet").put(info); // put a reference to info
setTimeout(() => {
info.get("name").put("fido"); // actually make info into a node
}, 2000);
console.log(test_name, await gun.get("foo").get("pet")); // will be called after 2 seconds
I have investigated further and it seems that this only works when using gun and not gun.user(). This is not great as user should inherit the gun functions and I would expect them to work the same...
This is a larger code example highlighting the differences:
const run = async () => {
localStorage.clear();
const gun = Gun();
const user = gun.user();
user.create("alice", "alicepass", () => {
user.auth("alice", "alicepass", async (ack) => {
test(user, "user"); // test the gun user. This will log "user undefined" (does not work)
})
})
test(gun, "gun"); // test on just gun. This will log "gun {_: {…}, name: 'fido'}" (does work)
}
async function test(gun, test_name){
const info = gun.get("foo").get("info");
gun.get("foo").get("pet").put(info);
setTimeout(() => {
info.get("name").put("fido");
}, 2000);
console.log(test_name, await gun.get("foo").get("pet"));
}
Edit 01:
Issue was originally called "Buggy behaviour when awaiting chains" It seems that doing .on will not fire if you put a reference to a node, that contains only a primitive value...?
gun.get("foo").get("name").on(name => console.log("name is: ", name)); // never runs
const thing = gun.get("thing").get("element").put("alice");
gun.get("foo").get("name").put(thing);
Original Issue
You can await gun chain and get the value residing at them. This lists some examples, illustrating buggy behaviour.
I created these tests in a .html file using the script import of gun.
This works:
const name = await gun.get("foo").get("name"); // there is nothing here...
console.log(name); // will log undefined
This works:
const thing = gun.get("thing").get("element").put({val: "alice"});
gun.get("foo").get("name").put(thing);
const name = await gun.get("foo").get("name");
console.log(name); // will log alice
This does NOT work:
const thing = gun.get("thing").get("element").put("alice");
gun.get("foo").get("name").put(thing);
const name = await gun.get("foo").get("name"); // stalls
console.log(name); // will never be called
gun is not promise/async based..
the best way to handle async stuff is to wrap with your own promise logic like this example
var Gun = require("gun")
var gun = Gun();
async function getData() {
return new Promise((res) => {
var chain = gun.get("test").get("hello").on((data) => {
if (data) {
chain.off();
res(data)
}
})
})
}
async function putData(data) {
gun.get("test").get("hello").put(data)
return await getData()
}
async function run() {
var data = await putData("world");
console.log(data)
}
run();
gun is not promise/async based..
the best way to handle async stuff is to wrap with your own promise logic like this example
I believe this is very close to what is implemented already in gun.then and what I think is used to "trick" js into woking with await's - because for the most part awaiting works fine. see docs
I realized however, that the issue is not so much a problem with await but that in general the .on call is not fired!
This does not work:
gun.get("foo").get("name").on(name => console.log("name is: ", name)); // never runs
const thing = gun.get("thing").get("element").put("alice");
gun.get("foo").get("name").put(thing);