Using DefineMap's `value` behavior to produce "middle tier" events

DefineMap’s value behavior adds a lot of event-stream power to DefineMap properties. For example, I can use it here to switch a streamIsOn property to false after a user leaves the page for 1hr:

streamIsOn: {
    value({resolve, listenTo}) {
        resol
        var timer;
        listenTo(window,"blur", function(){
            timer = setTimeout(function(){
                resolve(false);
            },1000*60*60)
        })
        listenTo(document,"keypress", function(){
            clearTimeout(timer);
        })
        listenTo(document, "click", function(){
            clearTimeout(timer);
        });
    }
}

Lately, I’ve been wanting to produce “middle tier” events that other properties could listen to. The following shows how I can create a userInteraction property that I’m using to dispatch "userInteraction" events:

userInteraction: {
    value({resolve, listenTo}) {
        listenTo(document, "click", function(){
            resolve({})
        });
        listenTo(document,"keypress", function(){
            resolve({})
        })
    }
},
streamIsOn: {
    value({resolve, listenTo}) {
        var timer;
        listenTo("userInteraction", function(){
            clearTimeout(timer);
        });
        listenTo(window,"blur", function(){
            timer = setTimeout(function(){
                resolve(false);
            },1000*60*60)
        })
    }
}

The secret is resolve({}). By passing a new object every time, resolve() will always change the value of the userInteraction so it will dispatch a new event every time.

2 Likes

@justinbmeyer this is awesome, do you recommend this approach or the reactive one using can-kefir to handle side-effects?

I think it depends on the app. Many apps have lots of basic logic, that getters and value() can easily solve. Once things get really hairy, I’d probably pull in kefir. It’s hard to say.

1 Like

Yes it makes sens, thank you!