Accessing previous values in the chain of gundb gets

397 Views Asked by At

In gundb it is convenient to chain get to find a node.

For example:

grandparent.get("children").map().get("children").map().once(function(grandchild,id) {...})

However the function gets called with the context of grandchild. What if I want to get a reference to parent (or any other intermediate node)?

The easiest way to do this is to break the query down:

grandparent.get("children").map().once(function(parent,id){
    parent.get("children").map().once(function(child,id){
         ...
    }
})

but this seems unnecessary. I did also try adding a function into map() which stored the current value in this, but this seemed pretty ugly.

Is there a preferred way of retaining or accessing state from previous chained gets?

1

There are 1 best solutions below

1
On

@Leo great question.

There are currently two approaches, and if you can think of a better one, let us know!

  1. Like what you said, do callback nesting (yuck!).
  2. Don't nest, and in grandchild callback use this.back()

Honorable mention: Use some extended API like gun.open() to load the full document from the parent downward.

this inside .on or .once callbacks is the chain context/reference of the data in the callback.

You can do quite a lot with (2), like:

If you want to grab more data from a parent, you can do this.back(2).get('some').get('other').get('data').once(cb).

However, most of the time you simply want the path of the grandparent, since map is dynamic you don't know what the path is.

In which case, you can get that from the chain meta data synchronously:

(assume path is a.b.c.d.e and we are on e)

this.back('get') // 'e'

this.back(2).back('get') // 'c'

If you want to forEach through each "back" chain, say for example, to get the full path from root:

var path = [];
this.back(function(at){ path.push(at.get) });
console.log(path.reverse().join('.'));
// 'a.b.c.d.e'

Moving forward:

  1. Documentation for .back() and internal chain metadata needs to improve.
  2. Providing full path for you, instead of having you to generate it, and other similar common things, may be added to the chain metadata in the future.
  3. More practically, you'll see more chain extensions that just automate it for you:

All of these ideas are possible to build/extend on GUN today, even .open() is less than 50 LOC chain extension! The community would love to help you build these extensions!

Like something similar to .open() but rather than loading document beneath the chain, loading the document back up the chain, for just that isolated path.

Or similar tooling, like passing in a schema to a parent, and an alternate version of .open() loading only the items in the schema instead of everything beneath.

This rapidly expands into other query engines ontop of GUN, like SQL, Mango, or the GraphQL one that already exists with realtime subscriptions!