npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

watchjs

v0.0.0

Published

A utility for watching object changes.

Downloads

673

Readme

Watch.js 1.2.0 Download

##Compatible with all browsers But still with some bugs with older browsers

About

Watch.JS is a small library that brings a lot of possibilities. You may know that the "Observer" design pattern involves executing some function when an observed object changes. Other libraries exist that do this, but with Watch.JS you will not have to change the way you develop. Take a look at the examples to see how simple it is to add Watch.JS to your code.

Observe the changes of one object attribute

//defining our object however we like
var ex1 = {
	attr1: "initial value of attr1",
	attr2: "initial value of attr2"
};

//defining a 'watcher' for an attribute
watch(ex1, "attr1", function(){
	alert("attr1 changed!");
});

//when changing the attribute its watcher will be invoked
ex1.attr1 = "other value";

Try out

Observe the changes of more than one object attribute

//defining our object however we like
var ex2 = {
    attr1: 0,
    attr2: 0,
    attr3: 0
};

//defining a 'watcher' for the attributes
watch(ex2, ["attr2", "attr3"], function(){
    alert("attr2 or attr3 changes!");
});

//when changing one of the attributes its watcher will be invoked
ex2.attr2 = 50;​

Try out

Observe the changes of all attributes of the object

//defining our object however we like
var ex3 = {
    attr1: 0,
    attr2: "initial value of attr2",
    attr3: ["a", 3, null]
};

//defining a 'watcher' for the object

watch(ex3, function(){
    alert("some attribute of ex3 changes!");
});

//when changing one of the attributes of the object the watcher will be invoked
ex3.attr3.push("new value");​

Try out

Remove a Watcher

var obj = {
    phrase: "hey",
    name: "buddy",
    alert: function(){
        alert(obj.phrase + " " + obj.name);
    },
    alert2: function(){
        alert(obj.name + ", " + obj.phrase);
    }
}
    
watch(obj, "name", obj.alert);
watch(obj, "name", obj.alert2);

obj.name = "johnny";

unwatch(obj, "name", obj.alert);

obj.name = "phil";​

Try out

More information about the change

//defining our object no matter which way we want
var ex1 = {
    attr1: "initial value of attr1",
    attr2: "initial value of attr2"
};

//defining a 'watcher' for an attribute
watch(ex1, "attr1", function(prop, action, newvalue, oldvalue){
    alert(prop+" - action: "+action+" - new: "+newvalue+", old: "+oldvalue+"... and the context: "+JSON.stringify(this));
});

//when changing the attribute its watcher will be invoked
ex1.attr1 = "other value";​

Try out

Don't worry about the Infinite Loop

If you don't want to call a second watcher in the current scope just set WatchJS.noMore to true and it will be reset to false when this watcher finishes.

//defining our object however we like
var ex1 = {
    attr1: "inicial value of attr1",
    attr2: "initial value of attr2"
};

//defining a 'watcher' for an attribute
watch(ex1, "attr1", function(){
    WatchJS.noMore = true; //prevent invoking watcher in this scope
    ex1.attr2 = ex1.attr1 + " + 1";
});

//defining other 'watcher' for another attribute
watch(ex1, "attr2", function(){
    alert("attr2 changes");
});


ex1.attr1 = "other value to 1"; //attr1 will be changed but will not invoke the attr2`s watcher

Try out

How deep you wanna go? Provide a level of children

//defining our object no matter which way we want
var ex = {
    //level 0
    l1a: "bla bla",
    l1b: {
        //level 1 or less
        l2a: "lo lo",
        l2b: {
            //level 2 or less
            deeper: "so deep"
        }           
    }
};

watch(ex, function(){
    alert("ex changes at lvl 2 or less");
}, 1);

watch(ex, function(){
    alert("ex changes at lvl 3 or less");
}, 2);


ex.l1b.l2b.deeper = "other value";


ex.l1b.l2b = "other value";

Try out

Chill out, no surprises, only expected attributes will be considered

After declaring a watcher for some object, when you add new attributes to this object and/or change it, the watcher will not be invoked. If you want the new attributes to be observed you need to specify the name of this new attributes.

//defining our object however we like
var ex6 = {
    attr1: 0,
    attr2: 1
};

//defining a 'watcher' for the object
watch(ex6, function(){
    alert("some attribute of ex6 changes!")
});

ex6.attr3 = null; //no watcher will be invoked
ex6.attr3 = "value"; //no watcher will be invoked​​​

Try out

An example how to define a watcher of an undefined attribute

//defining our object however we like
var ex6 = {
    attr1: 0,
    attr2: 1
};

//defining a 'watcher' for the specific attribute
watch(ex6, "attr3", function(){
    alert("attr3 changes")
});

ex6.attr3 = "value"; //watcher will be invoked

Try out

Invoke the watcher anytime you want

//defining our object however we like
var ex7 = {
    attr1: 0,
    attr2: 1
};

//defining a 'watcher' for the object
watch(ex7, function(){
    alert("some attribute of ex6 changes!")
});

callWatchers(ex7, "attr1"); //invoke the watcher​​

Try out

Compatible with JQuery

$(function(){

    var obj = {cont: 0};
    
    watch(obj, "cont", function(){
        alert("obj.cont = "+obj.cont);
    });

    $("#button").click(function(){
        obj.cont++;
    });
});

Try out

Different ways to build Classes/Objects and use Watch.JS

//open the browser log to view the messages

var Apple = function(type) {
    var _thisApple = this;
    this.type = type;
    this.color = "red";

    this.getInfo = function() {
        return this.color + ' ' + this.type + ' apple';
    };

    watch(this, function(){
        console.log("although we are using Watch.js the apple structure remains the same");
        for(var i in _thisApple){
            console.log(i+": "+_thisApple[i]);
        }
    });
};


var apple = new Apple("macintosh");
apple.type = "other";


var Banana = function(type) {
    var _thisBanana = this;
    this.type = type;
    this.color = "yellow";

    watch(this, function(){
        console.log("although we are using Watch.js the banana structure remains the same");
        for(var i in _thisBanana){
            console.log(i+": "+_thisBanana[i]);
        }
    });
};

Banana.prototype.getInfo = function() {
    return this.color + ' ' + this.type + ' banana';
};

var banana = new Banana("Cavendish");
banana.type = "other";

var orange = {
    type: "pocan",
    color: "orange",
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    }
};

watch(orange, function(){
    console.log("although we are using Watch.js the orange structure remains the same");

    for(var i in orange){
        console.log(i+": "+orange[i]);
    }
});

orange.type = "other";

Try out