5

I'm learning JavaScript Proxy .

By using set trap i only want to add even number to Array. But every time throw

Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'length'

Here is my code example.

//Only even numbers will be added here. We are using Js Proxy

let evenNumbers = [];

evenNumbers = new Proxy(evenNumbers, {
    set(target, p, value, receiver) {
        if ( (value % 2) === 0 ) {
            target[p] = value;
            return true
        }else {
            return false;
        }

    }
});

evenNumbers.push(2);
sahed moral
  • 345
  • 3
  • 13

2 Answers2

7

You neet to return true for both cases, because

Return value

The set() method should return a boolean value.

  • Return true to indicate that assignment succeeded.
  • If the set() method returns false, and the assignment happened in strict-mode code, a TypeError will be thrown.

push calls the proxy twice, one by pushing the value and another times to change the length property. To avoid unnecessary more action whithin in this proxy, you could exit early with this unwanted property.

let evenNumbers = [];

evenNumbers = new Proxy(evenNumbers, {
    set (target, p, value, receiver) {
        if (p === 'length') return true; // exclude this property
        if (value % 2 === 0) {
            target[p] = value;
        }
        return true;
    }
});

evenNumbers.push(2);
console.log(evenNumbers.length); // 1
evenNumbers.push(3);
console.log(evenNumbers.length); // Still 1
console.log(evenNumbers);        // [ 2 ]
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

The issue is that the function .push() tries to update the length (evenNumbers.length = 1), and that's not being allowed by the trap.

Try this:

let evenNumbers = [];

evenNumbers = new Proxy(evenNumbers, {
    set(target, p, value, receiver) {
        if ( isFinite(p) ) {
            // The key is a number (index), so there's code trying to add/change an element of the array.
            if ( (value % 2) === 0 ) {
                target[p] = value;
                return true
            }else {
                return false;
            }
        } else {
            return true;
        }
    }
});

evenNumbers.push(2); // OK
evenNumbers.push(3); // TypeError
D. Pardal
  • 6,173
  • 1
  • 17
  • 37