Gedi, an absurdly powerful model API

logo

Firstly, what’s gedi?

git: https://github.com/gaffa-tape/gedi
npm: https://npmjs.org/package/gedi

Gedi is model API wrapper. It Allows you to get and set, and remove to/from an object, and bind to changes that occur due to sets/removes.

Simple usage:

    // Set up the models data
    var model = new Gedi({
        thing: 2,
        lifeforms:{
            dogs:[
                {
                    name: "scruffy",
                    age:8
                },
                {
                    name: "spot",
                    age:4
                }
            ],
            users:[
                {
                    name: "bob",
                    age: 20
                },
                {
                    name: "john",
                    age:45
                }
            ]
        }
    });

    // get
    model.get('[thing]'); // --> 2

    // set
    model.set('[thing]', 5);

    // get after set
    model.get('[thing]'); // --> 5

    // bind to [thing]
    model.bind('[thing]', function(event){
        // this callback is called when [thing] changes.
        // event.getValue() returns the value of [thing]
    });
    

You can throw a parent path on the end of get/set/etc.. to make all bindings relative to it.

    model.get('[dogs]'); // --> undefined

    model.get('[lifeforms/dogs]'); // --> Array of dogs.

    // here, [dogs] will be relative to [lifeforms]
    model.get('[dogs]', '[lifeforms]'); // --> Array of dogs.
    

Why square braces?

Because gedi is more powerfull than just an object watcher.

you can pull data out via expressions…

    model.get('(last [lifeforms/dogs]).name'); // --> "spot"
    

And even bind callbacks to expressions…

    model.bind('(last [lifeforms/dogs]).name', function(event){
        // this callback is called when [lifeforms/dogs] changes.
        // event.getValue() returns the value of (last [lifeforms/dogs]).name
    });
    

However there was one thing I’d always thought would be awesome, and i’ve recently made some pretty big changes to how gedi works under the covers to allow.

    // Set the last item in [lifeforms/dogs] to a different dog
    model.set('(last [lifeforms/dogs])', {name: "ellie", age: 2});
    

Gedi can now keep track of paths throughout the execution of an expression, and perform useful opperations using the resulting path.

This is pretty exciting to me, expecially for how it can be used in gaffa.

You can also perform opperations on the result of a filter/map/slice/concat/etc.. eg.

(fyi, the syntax for an anonymous function in gedi is {param1 param2 paramN functionBody})

remove all items in an array that match an expression.

    model.remove('(filter [dogs] {dog (> dog.age 7)})', '[lifeforms]');
    

set properties on all items across multiple arrays that match an expression. (TO RIDICULOUS, AND BEYOND!)

    model.set('(map (filter (concat [dogs] [users]) {item (> item.age 5)}) {item item.label})', 'old!', '[lifeforms]');
    

And of course, any changes made using expressions cause model events to fire at the right paths.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s