Search code examples
javascriptmappingternary

Why is my JS Ternary ignoring the conditional argument where the affirmative should execute a map.set(k,v) function?


The goal is to map data- attributes from one element to another, but while ignoring certain attributes such as class, id, etc.

Here is a block:

    let ignoreList = ['class', 'id', 'name', 'value', 'type', 'src'];
    $(".some-class").on("click",function(event) {
        let attrMap = new Map();
        let attrs = event.target.attributes;
        $.each(attrs, function(e){
            console.log(`"${this.name}" is in ignoreList: ` + (ignoreList.indexOf(this.name) == 0).toString());
            ignoreList.indexOf(this.name) == 0 ? attrMap.set(this.name, this.value) : null;
        });
        console.log(attrs);
        console.log(attrMap);
    });

What I would have expected in the console would be:

"class" is in ignoreList: true
"data-one" is in ignoreList: false
"data-two" is in ignoreList: false
"data-three" is in ignoreList: false
"data-four" is in ignoreList: false
"data-five" is in ignoreList: false
"data-six" is in ignoreList: false

NamedNodeMap {0: class, 1: data-one, 2: data-two, 3: data-three, 4: data-four, 5: data-five, 6: data-six, class: class, data-one: data-one, data-two: data-two, data-three: data-three, data-four: data-four, …}

Map(6) {'data-one' => 'Lorem ipsum', 'data-two' => 'dolor sit amet', 'data-three' => 'purto ludus', 'data-four' => 'indoctum sit', …}

What I am getting in the console:
(repeated values ignored for brevity)

Map(1) {'class' => 'some-class'}

I have tried various logics in the conditional, such as < 0, == -1, != 0


Solution

  • If you do console.log(ignoreList.indexOf(this.name)) you'll get always -1 in your case, but you're forcefully trying to match the result of Array.prototype.indexOf with an index of == 0.

    Instead, to check if an array includes a value, use Array.prototype.includes() and save the Boolean result into a variable say isIgnored. Then you could use if (!isIgnored) /*set*/ or simply: !isIgnored && /*set*/, no ternary needed:

    const ignoreList = ['class', 'id', 'name', 'value', 'type', 'src'];
    
    const mapAttrs = (event) => {
    
      const attrMap = new Map();
      const attrs = event.currentTarget.attributes;
    
      [...attrs].forEach((attr) => {
        const isIgnored = ignoreList.includes(attr.name);
        console.log(`"${attr.name}" is in ignoreList: ${isIgnored}`);
        !isIgnored && attrMap.set(attr.name, attr.value);
      });
      
      console.log(attrs);
      console.log(attrMap);
    };
    
    
    document.querySelectorAll(".some-class").forEach(el => {
      el.addEventListener("click", mapAttrs);
    });
                                                     
    <div
        class="some-class"
        data-one="one"
        data-two="two"
        data-three="three"
        data-four="four"
        data-five="five"
        data-six="six"
    >Open Dev tools Console (F12) and - Click me</div>