Gun: Can you solve this "Gun Get" puzzle for a nested object??

Created on 23 Mar 2019  路  5Comments  路  Source: amark/gun

Can you, using any of the available plugins or an external one from those listed, get an object with the keys contained in "obj"? Requirement: must use async/await.

var Gun = require('gun');
    var SEA = require('gun/sea');
    require('gun/lib/unset.js');
    require('gun/lib/open.js')
    require('gun/lib/load.js')  
    require('gun/lib/then.js');
var gun = Gun()
async function test(){
        var obj = {"property":"value","depth":{"is":"more_than_one"}};
        gun.get("key").put(obj);
        console.log("Put this away! : ",obj);
        var obj2 = await gun.get("key").then();
        console.log("Got this value",obj2);
}
test();

Will you get the full dict contain in obj? Or, will your result be this:

Got this value { _: { '#': 'key', '>': [Object] },
  depth: { '#': 'jtm3cjyqGvlGqFS2TIrN' },
  property: 'value' }

Can you get a result where the depth key contains the value {"is":"more_than_one"}?

Most helpful comment

Insanity but...

var Gun = require("gun");
var SEA = require("gun/sea");
require("gun/lib/unset.js");
require("gun/lib/open.js");
require("gun/lib/load.js");
require("gun/lib/then.js");
var gun = Gun();
async function test() {
  var obj = { property: "value", depth: { is: "more_than_one" } };
  gun.get("key").put(obj);
  console.log("Put this away! : ", obj);
  var obj2 = await gun
    .get("key")
    .then()
    .then(async v => {
      let soul = Gun.node.soul(v);
      let keys = Object.keys(v).filter(k => k !== "_");
      let all = keys.map(key =>
        gun
          .get(soul)
          .get(key)
          .then()
      );

      let results = await Promise.all(all);
      return keys.reduce((result, key, i) => {
        result[key] = results[i];
        return result;
      }, {});
    });
  console.log("Got this value", obj2);
}
test();

Returns:

Got this value { depth:
   { _: { '#': 'jtm3zq9iSCH5OWncpQuk', '>': [Object] },
     is: 'more_than_one' },
  property: 'value' }

Here is the sandbox
https://codesandbox.io/s/5k71k3xrmp?fontsize=14

All 5 comments

Insanity but...

var Gun = require("gun");
var SEA = require("gun/sea");
require("gun/lib/unset.js");
require("gun/lib/open.js");
require("gun/lib/load.js");
require("gun/lib/then.js");
var gun = Gun();
async function test() {
  var obj = { property: "value", depth: { is: "more_than_one" } };
  gun.get("key").put(obj);
  console.log("Put this away! : ", obj);
  var obj2 = await gun
    .get("key")
    .then()
    .then(async v => {
      let soul = Gun.node.soul(v);
      let keys = Object.keys(v).filter(k => k !== "_");
      let all = keys.map(key =>
        gun
          .get(soul)
          .get(key)
          .then()
      );

      let results = await Promise.all(all);
      return keys.reduce((result, key, i) => {
        result[key] = results[i];
        return result;
      }, {});
    });
  console.log("Got this value", obj2);
}
test();

Returns:

Got this value { depth:
   { _: { '#': 'jtm3zq9iSCH5OWncpQuk', '>': [Object] },
     is: 'more_than_one' },
  property: 'value' }

Here is the sandbox
https://codesandbox.io/s/5k71k3xrmp?fontsize=14

Thanks dawg. I tried to wrap that function into a chain like the others but I couldn't figure it out. In the end i think i went with what the other nice gitter man suggested . Remember that the WAIT Is important

    async function retrieve(gunNode){
        return new Promise((resolve,reject)=>{
            gunNode.open(function(value){
                console.log("Got this obj4",value);
                resolve(value);
            },{wait:199});
        });
    }
        gun.retrieve=retrieve;
    async function test(){
        var obj = {"property":"value","depth":{"is":"more_than_one"}};
        gun.get("key").put(obj);
        console.log("Put this away! : ",obj);
        var obj2 = await gun.retrieve(gun.get("key"));
        console.log("Got this value",obj2);
 }
> test();

See comment below!!

@omarzion THANKS SO MUCH for jumping into the community and helping <3 <3 <3

@projectoblio do you know what broke? Because 0.2019.323 has some critical updates - I had to bump the middle number away from 9 to date 2019 because while the API should be the same, old data won't work. Is it that your old data is gone? You should probably use ^0.A.B package.json notation so you don't get messed up on upgrades like this. :/ Sorry!

Wanted to double check... does wrapping .load(cb in a Promise not work?
I see @omarzion you include it, but don't use it, and manually recurse to find sub-data yourself (this is what .load should do automatically for you).

I think my issue was that last night I tried my promise-wrap without the {wait:99} included. It worked in a test script so last night, I put it in my code and kept working. This morning I tried the script inside my codebase and it still wasn't working. Basically, this inconsistency was caused by not having wait inside the larger codebase while it worked in the test script. I edited my earlier comment to include wait to avoid any confusion.

It would be great if you could Promisfy load in-chain, but if it's not worth it it's fine

async function retrieveWithWait(gunNode){
    return new Promise((resolve,reject)=>{
        gunNode.load(function(data){
            resolve(data);
        },{wait:199});
    });
}
async function retrieve(gunNode){
    return new Promise((resolve,reject)=>{
        gunNode.load(function(data){
            resolve(data);
        });
    });
}
async function test(){
        var obj = {"property":"value","depth":{"is":"more_than_one"}};
        gun.get("key").put(obj);
        console.log("Put this away! : ",obj);
                var obj1 = await gun.get("key"); // returns a gun node, see wikipedia on Graph DBs for it
        console.log("Got this value with then",obj1);
        var obj2 = await gun.get("key").then(); // works with strings but not nested
        console.log("Got this value with then",obj2);
        var obj3 = await gun.get("key").load().then(); // load and "then" don't work together
        console.log("Got this value with .load().then()",obj4);
        var obj4 = await gun.get("key").load(); // works with only a callback, not await
        console.log("Got this value with .load()",obj4);
        var obj5 = await retrieve(gun.get("key")); // works if the data is very small
        console.log("Got this value with promise wrap",obj5);
        var obj6 = await retrieveWithWait(gun.get("key")); // works if the data is large 
        console.log("Got this value with promise wrap and wait",obj6);
}
test();

This code does work with promise wrap (last two cases). Inside my greater library only obj6 produced the result.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

34r7h picture 34r7h  路  8Comments

jeffbski picture jeffbski  路  5Comments

danfinlay picture danfinlay  路  3Comments

ivkan picture ivkan  路  6Comments

TimeTravelersHackedMe picture TimeTravelersHackedMe  路  6Comments