Skip to content
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

Referencing nodes that hold only primitive values #1359

Open
gustavcorpas opened this issue Jan 23, 2024 · 2 comments
Open

Referencing nodes that hold only primitive values #1359

gustavcorpas opened this issue Jan 23, 2024 · 2 comments

Comments

@gustavcorpas
Copy link

gustavcorpas commented Jan 23, 2024

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
@bmatusiak
Copy link
Collaborator

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();

@gustavcorpas
Copy link
Author

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);       

@gustavcorpas gustavcorpas changed the title Buggy behaviour when awaiting chains Referencing nodes that hold only primitive values Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants