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

ractive.unset(keypath) would be great! #1649

Closed
pakastin opened this issue Jan 21, 2015 · 13 comments
Closed

ractive.unset(keypath) would be great! #1649

pakastin opened this issue Jan 21, 2015 · 13 comments

Comments

@pakastin
Copy link

Ractive.js is missing ractive.unset(keypath). When you have an object, you can't use delete, because binding wouldn't work. Setting the whole object again without the key is fine when you have small object, but when you have large dictionary, it gets slow..

You could use ractive.set(keypath, 'undefined'), but the key is still there, it's just undefined.

@martypdx
Copy link
Contributor

You can use `ractive.update('obj.key') with delete, and performance seems pretty quick: http://jsfiddle.net/eswmv63o/.

You could put that logic in an observer (http://jsfiddle.net/eswmv63o/2/):

r.observe('foo.*', function(n, o, k, property){
    if(typeof n === 'undefined'){
        delete r.get('foo')[property];
        r.update(k);
    }
}, { init: false });

// this now deletes the property as well and updates the view...
r.set('foo.a30');

Or you could create your own ractive.unset() (http://jsfiddle.net/eswmv63o/4/):

Ractive.prototype.unset = function(keypath){
    var lastDot = keypath.lastIndexOf( '.' ),
        parent = keypath.substr( 0, lastDot ),
        property = keypath.substring( lastDot + 1 );

    this.set(keypath);
    delete this.get(parent)[property];
    return this.update(keypath);
}

// property is now deleted and updated...
r.unset('foo.a30');

@Rich-Harris
Copy link
Member

Big +1 on @martypdx's prototype hacking solution. Based on how often I say that, I wonder if it's time we had a proper story around mixins, so that it'd be possible to do things like...

require('ractive-mixins-unset');

...rather than pasting code snippets. But I digress. It would certainly be possible to add this to the core API, but in accordance with #1568 I think we should hold off unless it turns out this is a common need. So I'm going to close this issue, but we can keep the discussion going here by all means - if anyone else out there wishes there was an unset() method then please weigh in.

@pakastin
Copy link
Author

It would be great to be able to use Ractive.js straight with MongoDB's oplog, which reports all the changes like following:

{$set: {'a.b.c': 'lorem ipsum'}, $unset: {'a.b.d': true}}

So I could use like so:

ractive.set(changes.$set)

and

ractive.unset(changes.$unset)

@arxpoetica
Copy link

Actually, @Rich-Harris I just ran into this need. We've been using undefined as a sort of stop-gap in lieu of unset, but I just discovered that (strangely) (and this might need to be another ticket) setting a variable to undefined does not always work.

Specifically we've been working with video.js, and I check a player data variable, and if it exists, we'll reuse the player (instead of creating another one). On teardown, however, I make sure to actually "unset" that variable, and we've been using this.set('player', undefined) but I just now discovered that setting to undefined doesn't always work.

I verified this by changing it to null and it suddenty started working consistently. In any case, I'm probably going to use @martypdx's unset hack above, but it would be nice to actually have that built in. There are numerous instances where we've been setting things to undefined, but I'm going to be more hesitant to use that in the future, knowing that it's problematic. Let me know if you want me to open a new ticket. 👍

@greglearns
Copy link

+1 I have wished for unset several times.

@arxpoetica
Copy link

Following the likes of other libraries and normal js convention, might make more sense to call it remove. I've been thinking more and more this should actually be a feature, not a mixin.

@saiichihashimoto
Copy link

+1 for the feature
+1 to call it remove
+0.5 to call it del or unset

@psy21d
Copy link

psy21d commented Jan 16, 2016

yes, this is very important option!
I need to use it many times

@psy21d
Copy link

psy21d commented Jan 16, 2016

now I use delete for object keys:

    var smto = {
        a:'a',
        b:'b'
    }

    var ractive = new Ractive({
        el: "#ractive_change",
        template: "#ractive_change_template",
        data: {
            smto: smto
        }
    });

    // then
    delete smto.a;
    // ok, poh

@peterdenev
Copy link

Thanks @martypdx
There is my little change of your code in case when you try to change the root and have no "." (dot)

Ractive.prototype.unset = function(keypath){                
                var parent = '',
                    property = keypath,
                    lastDot = keypath.lastIndexOf( '.' );

                if(lastDot!==-1){
                    parent = keypath.substr( 0, lastDot );
                    property = keypath.substring( lastDot + 1 );
                }               

                this.set(keypath);
                delete this.get(parent)[property];
                return this.update(keypath);
            }

@BigWillie
Copy link

@peterdenev and @martypdx - thanks :) Just what I was after. I will be using this a lot.

@briancray
Copy link

Any thought on revisiting this as a part of 0.9 api? Definitely something that's been missing on my side as well as the others here.

@pakastin
Copy link
Author

I eventually went and did my own view library, which better suits to my needs https://redom.js.org 😎👍

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

10 participants