diff --git a/package.json b/package.json index ef6d88e..8915fa8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gawk", - "version": "3.2.2", + "version": "3.3.0", "description": "Observable JavaScript object model", "main": "./dist/index.js", "author": "Chris Barber (https://github.com/cb1kenobi)", diff --git a/src/index.js b/src/index.js index 012794a..fd56ce0 100644 --- a/src/index.js +++ b/src/index.js @@ -432,7 +432,7 @@ gawk.watch = function watch(subject, filter, listener) { * Removes a listener from the specified gawked object. * * @param {Object|GawkObject|Array|GawkArray} subject - The object to unwatch. - * @param {Function} listener - The function to call when something changes. + * @param {Function} [listener] - The function to call when something changes. * @returns {GawkObject|GawkArray} Returns a gawked object or array depending on * the input object. */ @@ -441,13 +441,20 @@ gawk.unwatch = function unwatch(subject, listener) { throw new TypeError('Expected source to be a GawkArray or GawkObject'); } - if (typeof listener !== 'function') { - throw new TypeError('Expected listener to be a function'); + if (listener) { + if (typeof listener !== 'function') { + throw new TypeError('Expected listener to be a function'); + } + subject.__gawk__.listeners.delete(listener); + subject.__gawk__.previous.delete(listener); + } else { + // remove all listeners + for (const [ listener, filter ] of subject.__gawk__.listeners) { + subject.__gawk__.listeners.delete(listener); + subject.__gawk__.previous.delete(listener); + } } - subject.__gawk__.listeners.delete(listener); - subject.__gawk__.previous.delete(listener); - return subject; }; diff --git a/test/test-watch.js b/test/test-watch.js index 81a0ac7..7ed34f0 100644 --- a/test/test-watch.js +++ b/test/test-watch.js @@ -546,10 +546,6 @@ describe('gawk.unwatch()', () => { }); it('should fail to unwatch with non-function listener', () => { - expect(() => { - gawk.unwatch(gawk({})); - }).to.throw(TypeError, 'Expected listener to be a function'); - expect(() => { gawk.unwatch(gawk({}), 'foo'); }).to.throw(TypeError, 'Expected listener to be a function'); @@ -575,6 +571,29 @@ describe('gawk.unwatch()', () => { expect(count).to.equal(2); }); + it('should unwatch all listeners', () => { + const gobj = gawk({}); + let count = 0; + + gawk.watch(gobj, () => { + count++; + }); + + gawk.watch(gobj, () => { + count++; + }); + + gobj.a = 'b'; + gobj.c = 'd'; + + gawk.unwatch(gobj); + + gobj.e = 'f'; + gobj.g = 'h'; + + expect(count).to.equal(4); + }); + it('should unwatch GawkArray changes', () => { const garr = gawk(['a']); let count = 0;