Search code examples
javascriptfunctionglobal-variablesaddeventlistenervariable-assignment

JavaScript addEventListener calls function but fails to update global variable


Bear with me, as I am a novice.

I'm coding in JavaScript and using an .addEventListener on document.getElementById("texts") to track changes in an HTML dropdown. The .addEventListener calls the function changeTextValue whenever a selection is made. This part is working, as I can console.log from within the function, and my conditional logic within the function is properly executed and sent to the console from within the function. However, the whole point of the function is to update a variable (text) outside the function every time the mouse event occurs. I've assigned the function to the variable, and I've included a return statement in the function with the proper local variable. All of this is working, the assignment is initially made outside the scope of the function and prints to the console when the page first loads. However, the variable value never updates outside the function when the mouse event occurs. Whereas the console.logs within the function do update when the event occurs.

I tried merely initializing the variable text without assigning it a value. But then I get an error that 'text.toLowerCase()' is undefined.

I tried initializing text as an empty array. And then inserting text (in place of chosenText) into the function, prefixing it with window to access it as a global variable. This threw up an error: 'text.toLowerCase()' is not a function. This error goes away when I return the code to the way I am posting it, keeping the text variable outside the function, but assigning the function to the variable.

I feel like I'm missing something basic. Thanks for your help.

'use strict';

const mobyDickText=`Moby Dick text....`;
const huckFinnText=`Huck Finn text....`;
let dropdown = document.getElementById("texts");
let pick=dropdown.value;
const title=pick;
let chosenText;
let text= changeTextValue();
let letterCount;
let lowercaseText;

document.getElementById("book-title").innerHTML = title;

function changeTextValue() {
    pick = dropdown.value;
    if (pick === "huckFinnText") {
         chosenText = huckFinnText;
        console.log(chosenText);
    } else if (pick === "mobyDickText") {
        chosenText = mobyDickText;
        console.log(chosenText);
    } return chosenText;
}

console.log(text);

document.getElementById("texts").addEventListener("change", changeTextValue);

function countFunction(letter) {
    let letterCount=0;
    lowercaseText=text.toLowerCase();
    for (let i=0; i<=text.length-1; i++) {
      if (letter === lowercaseText.charAt(i)) {
          letterCount++;
      }
    } return letterCount;
  } 

const a = countFunction("a");
const b = countFunction("b");
const c = countFunction("c");
const d = countFunction("d");
const e = countFunction("e");
const f = countFunction("f");
const g = countFunction("g");
const h = countFunction("h");
const i = countFunction("i");
const j = countFunction("j");
const k = countFunction("k");
const l = countFunction("l");
const m = countFunction("m");
const n = countFunction("n");
const o = countFunction("o");
const p = countFunction("p");
const q = countFunction("q");
const r = countFunction("r");
const s = countFunction("s");
const t = countFunction("t");
const u = countFunction("u");
const v = countFunction("v");
const w = countFunction("w");
const x = countFunction("x");
const y = countFunction("y");
const z = countFunction("z");

const letters = {
    "A": a,
    "B": b,
    "C": c,
    "D": d,
    "E": e,
    "F": f,
    "G": g,
    "H": h,
    "I": i,
    "J": j,
    "K": k,
    "L": l,
    "M": m,
    "N": n,
    "O": o,
    "P": p,
    "Q": q,
    "R": r,
    "S": s,
    "T": t,
    "U": u,
    "V": v,
    "W": w,
    "X": x,
    "Y": y,
    "Z": z
};

let sortable = [];
for (var num in letters) {
    sortable.push([num, letters[num]]);
}
const sorted=sortable.sort(function(a, b) {
    return b[1] - a[1];
});

let sortedNumbers = [];
for (var value in sorted) {
    sortedNumbers.push(sorted[value][1]);
}

let sortedLetters = [];
for (var value in sorted) {
    sortedLetters.push(sorted[value][0]);
}

for (let item=0; item<sorted.length; item++) {
    let strLetter = item.toString();
    document.getElementById(strLetter).innerHTML = sortedLetters[item];
}

for (let item=0; item<sorted.length; item++) {
    let strNumber = item.toString() + "n";
    document.getElementById(strNumber).innerHTML = sortedNumbers[item].toLocaleString();
} 

let total=0;
for (let item=0; item<sorted.length; item++) {
    total += sortedNumbers[item];
} document.getElementById("total").innerHTML = total.toLocaleString();

let percent = [];
for (var num in sortedNumbers) {
    percent.push((sortedNumbers[num] / total) * 100);
    document.getElementById(num + "p").innerHTML = percent[num].toFixed(1) + "%";
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <main id="main">
        <form id="form">
            <select id= "texts" name="texts" class="select">
                <option value="mobyDickText" id="mobyDick">Moby Dick</option> 
                <option value="huckFinnText" id="huckFinn">Huck Finn</option>
            </select>
        </form>
        <table class="result">
            <tbody>
                <th class="title" colspan="3" id="book-title"></th>
                <tr><td id="0" class="letter"></td><td id="0n" class="number"></td><td id="0p" class="percent"></td></tr>
                <tr><td id="1" class="letter"></td><td id="1n" class="number"></td><td id="1p" class="percent"></td></tr>
                <tr><td id="2" class="letter"></td><td id="2n" class="number"></td><td id="2p" class="percent"></td></tr>
                <tr><td id="3" class="letter"></td><td id="3n" class="number"></td><td id="3p" class="percent"></td></tr>
                <tr><td id="4" class="letter"></td><td id="4n" class="number"></td><td id="4p" class="percent"></td></tr>
                <tr><td id="5" class="letter"></td><td id="5n" class="number"></td><td id="5p" class="percent"></td></tr>
                <tr><td id="6" class="letter"></td><td id="6n" class="number"></td><td id="6p" class="percent"></td></tr>
                <tr><td id="7" class="letter"></td><td id="7n" class="number"></td><td id="7p" class="percent"></td></tr>
                <tr><td id="8" class="letter"></td><td id="8n" class="number"></td><td id="8p" class="percent"></td></tr>
                <tr><td id="9" class="letter"></td><td id="9n" class="number"></td><td id="9p" class="percent"></td></tr>
                <tr><td id="10" class="letter"></td><td id="10n" class="number"></td><td id="10p" class="percent"></td></tr>
                <tr><td id="11" class="letter"></td><td id="11n" class="number"></td><td id="11p" class="percent"></td></tr>
                <tr><td id="12" class="letter"></td><td id="12n" class="number"></td><td id="12p" class="percent"></td></tr>
                <tr><td id="13" class="letter"></td><td id="13n" class="number"></td><td id="13p" class="percent"></td></tr>
                <tr><td id="14" class="letter"></td><td id="14n" class="number"></td><td id="14p" class="percent"></td></tr>
                <tr><td id="15" class="letter"></td><td id="15n" class="number"></td><td id="15p" class="percent"></td></tr>
                <tr><td id="16" class="letter"></td><td id="16n" class="number"></td><td id="16p" class="percent"></td></tr>
                <tr><td id="17" class="letter"></td><td id="17n" class="number"></td><td id="17p" class="percent"></td></tr>
                <tr><td id="18" class="letter"></td><td id="18n" class="number"></td><td id="18p" class="percent"></td></tr>
                <tr><td id="19" class="letter"></td><td id="19n" class="number"></td><td id="19p" class="percent"></td></tr>
                <tr><td id="20" class="letter"></td><td id="20n" class="number"></td><td id="20p" class="percent"></td></tr>
                <tr><td id="21" class="letter"></td><td id="21n" class="number"></td><td id="21p" class="percent"></td></tr>
                <tr><td id="22" class="letter"></td><td id="22n" class="number"></td><td id="22p" class="percent"></td></tr>
                <tr><td id="23" class="letter"></td><td id="23n" class="number"></td><td id="23p" class="percent"></td></tr>
                <tr><td id="24" class="letter"></td><td id="24n" class="number"></td><td id="24p" class="percent"></td></tr>
                <tr><td id="25" class="letter"></td><td id="25n" class="number"></td><td id="25p" class="percent"></td></tr>
                <tr><td class="footer" colspan="3" id="total"></td></tr>
            </tbody>
        </table>
    </main>  
    <script src="script.js"></script>
  </body>
</html>
```


Solution

  • ok, here you go :)

    you werent too far off

    'use strict';
    
    let aCount = 0,
      bCount = 0,
      cCount = 0,
      dCount = 0,
      eCount = 0,
      fCount = 0,
      gCount = 0,
      hCount = 0,
      iCount = 0,
      jCount = 0,
      kCount = 0,
      lCount = 0,
      mCount = 0,
      nCount = 0,
      oCount = 0,
      pCount = 0,
      qCount = 0,
      rCount = 0,
      sCount = 0,
      tCount = 0,
      uCount = 0,
      vCount = 0,
      wCount = 0,
      xCount = 0,
      yCount = 0,
      zCount = 0;
    
    const mobyDickText=`Moby Dick text....`;
    const huckFinnText=`Huck Finn text....`;
    let dropdown = document.getElementById("texts");
    let pick=dropdown.value;
    const title=pick;
    let chosenText;
    
    
    //edit
    
    let text
    
    
    
    let letterCount;
    let lowercaseText;
    
    document.getElementById("book-title").innerHTML = title;
    
    function changeTextValue() {
      
        pick = dropdown.value;
        if (pick === "huckFinnText") {
             chosenText = huckFinnText;
            console.log(chosenText);
        } else if (pick === "mobyDickText") {
            chosenText = mobyDickText;
            console.log(chosenText);
        } 
    
    
    //edit
    
        text=chosenText;
        update();
        //return chosenText;
    
    
    
    
    }
    
    
    
    
    
    
    
    
    //edit
    
    //console.log(text);
    changeTextValue();
    
    
    
    
    
    document.getElementById("texts").addEventListener("change", changeTextValue);
    
    function countFunction(letter) {
        let letterCount=0;
        lowercaseText=text.toLowerCase();
        for (let i=0; i<=text.length-1; i++) {
          if (letter === lowercaseText.charAt(i)) {
              letterCount++;
          }
        } return letterCount;
      } 
    
    
    
    
    
    //edit
    
    function update(){
      
      
    const a = countFunction("a");
    const b = countFunction("b");
    const c = countFunction("c");
    const d = countFunction("d");
    const e = countFunction("e");
    const f = countFunction("f");
    const g = countFunction("g");
    const h = countFunction("h");
    const i = countFunction("i");
    const j = countFunction("j");
    const k = countFunction("k");
    const l = countFunction("l");
    const m = countFunction("m");
    const n = countFunction("n");
    const o = countFunction("o");
    const p = countFunction("p");
    const q = countFunction("q");
    const r = countFunction("r");
    const s = countFunction("s");
    const t = countFunction("t");
    const u = countFunction("u");
    const v = countFunction("v");
    const w = countFunction("w");
    const x = countFunction("x");
    const y = countFunction("y");
    const z = countFunction("z");
    
    const letters = {
        "A": a,
        "B": b,
        "C": c,
        "D": d,
        "E": e,
        "F": f,
        "G": g,
        "H": h,
        "I": i,
        "J": j,
        "K": k,
        "L": l,
        "M": m,
        "N": n,
        "O": o,
        "P": p,
        "Q": q,
        "R": r,
        "S": s,
        "T": t,
        "U": u,
        "V": v,
        "W": w,
        "X": x,
        "Y": y,
        "Z": z
    };
    
    let sortable = [];
    for (var num in letters) {      //console.log(num,letters[num]);
        sortable.push([num, letters[num]]);
    }
    const sorted=sortable.sort(function(a, b) {
        return b[1] - a[1];
    });
    
    let sortedNumbers = [];
    for (var value in sorted) {
        sortedNumbers.push(sorted[value][1]);
    }
    
    let sortedLetters = [];
    for (var value in sorted) {
        sortedLetters.push(sorted[value][0]);
    }
    
    for (let item=0; item<sorted.length; item++) {
        let strLetter = item.toString();
        document.getElementById(strLetter).innerHTML = sortedLetters[item];
    }
    
    for (let item=0; item<sorted.length; item++) {
        let strNumber = item.toString() + "n";
        document.getElementById(strNumber).innerHTML = sortedNumbers[item].toLocaleString();
    } 
    
    let total=0;
    for (let item=0; item<sorted.length; item++) {
        total += sortedNumbers[item];
    } document.getElementById("total").innerHTML = total.toLocaleString();
    
    let percent = [];
    for (var num in sortedNumbers) {
        percent.push((sortedNumbers[num] / total) * 100);
        document.getElementById(num + "p").innerHTML = percent[num].toFixed(1) + "%";
    }
    
    
    
    //edit
    
    }//update
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="styles.css">
      </head>
      <body>
        <main id="main">
            <form id="form">
                <select id= "texts" name="texts" class="select">
                    <option value="mobyDickText" id="mobyDick">Moby Dick</option> 
                    <option value="huckFinnText" id="huckFinn">Huck Finn</option>
                </select>
            </form>
            <table class="result">
                <tbody>
                    <th class="title" colspan="3" id="book-title"></th>
                    <tr>
                          <td id="0" class="letter"></td>
                          <td id="0n" class="number"></td>
                          <td id="0p" class="percent"></td>
                    </tr>
                    <tr><td id="1" class="letter"></td><td id="1n" class="number"></td><td id="1p" class="percent"></td></tr>
                    <tr><td id="2" class="letter"></td><td id="2n" class="number"></td><td id="2p" class="percent"></td></tr>
                    <tr><td id="3" class="letter"></td><td id="3n" class="number"></td><td id="3p" class="percent"></td></tr>
                    <tr><td id="4" class="letter"></td><td id="4n" class="number"></td><td id="4p" class="percent"></td></tr>
                    <tr><td id="5" class="letter"></td><td id="5n" class="number"></td><td id="5p" class="percent"></td></tr>
                    <tr><td id="6" class="letter"></td><td id="6n" class="number"></td><td id="6p" class="percent"></td></tr>
                    <tr><td id="7" class="letter"></td><td id="7n" class="number"></td><td id="7p" class="percent"></td></tr>
                    <tr><td id="8" class="letter"></td><td id="8n" class="number"></td><td id="8p" class="percent"></td></tr>
                    <tr><td id="9" class="letter"></td><td id="9n" class="number"></td><td id="9p" class="percent"></td></tr>
                    <tr><td id="10" class="letter"></td><td id="10n" class="number"></td><td id="10p" class="percent"></td></tr>
                    <tr><td id="11" class="letter"></td><td id="11n" class="number"></td><td id="11p" class="percent"></td></tr>
                    <tr><td id="12" class="letter"></td><td id="12n" class="number"></td><td id="12p" class="percent"></td></tr>
                    <tr><td id="13" class="letter"></td><td id="13n" class="number"></td><td id="13p" class="percent"></td></tr>
                    <tr><td id="14" class="letter"></td><td id="14n" class="number"></td><td id="14p" class="percent"></td></tr>
                    <tr><td id="15" class="letter"></td><td id="15n" class="number"></td><td id="15p" class="percent"></td></tr>
                    <tr><td id="16" class="letter"></td><td id="16n" class="number"></td><td id="16p" class="percent"></td></tr>
                    <tr><td id="17" class="letter"></td><td id="17n" class="number"></td><td id="17p" class="percent"></td></tr>
                    <tr><td id="18" class="letter"></td><td id="18n" class="number"></td><td id="18p" class="percent"></td></tr>
                    <tr><td id="19" class="letter"></td><td id="19n" class="number"></td><td id="19p" class="percent"></td></tr>
                    <tr><td id="20" class="letter"></td><td id="20n" class="number"></td><td id="20p" class="percent"></td></tr>
                    <tr><td id="21" class="letter"></td><td id="21n" class="number"></td><td id="21p" class="percent"></td></tr>
                    <tr><td id="22" class="letter"></td><td id="22n" class="number"></td><td id="22p" class="percent"></td></tr>
                    <tr><td id="23" class="letter"></td><td id="23n" class="number"></td><td id="23p" class="percent"></td></tr>
                    <tr><td id="24" class="letter"></td><td id="24n" class="number"></td><td id="24p" class="percent"></td></tr>
                    <tr><td id="25" class="letter"></td><td id="25n" class="number"></td><td id="25p" class="percent"></td></tr>
                    <tr><td class="footer" colspan="3" id="total"></td></tr>
                </tbody>
            </table>
        </main>  
        <script src="script.js"></script>
      </body>
    </html>

    • i put the code that updated the table into a function called update

    • its seems the overall processing was done on a global variable named text, i didnt call changeTextValue to initialise it straight away

    • in changeValueText rather than returning the value, i assigned it to the global variable text, then called that update function

    • i waited until you confirmed the global variable had been set with a console.log then manually called your changeValueText so that update function was called and your table showed some results

    yeah you might be a novice but we all started there, your program showed ingenunity and you stroved to push yourself, well done :)