0

So, the code seems to work when I have the array of objects in the same JS file as the functions. As soon as I move the array to another file and then export it. The code won't run. Are there any smart people here that can find the error that makes it not run? If I remove defer type="module", from the script import it seems to run fine. But I need to make it an export module....

ERROR: Uncaught ReferenceError: updateResult is not defined at HTMLInputElement.oninput (page2.html:29)

// an object
export const playersArray = [
    {
        name: 'Darwin Núñez',
        number: 27,
        age: 23,
        position: 'Forward',
        image: 'nunez.png'
    },
    {
        name: 'Mohamed Salah',
        number: 11,
        age: 30,
        position: 'Midfielder',
        image: 'salah.png'
    },
    {
        name: 'Diogo Jota',
        number: 20,
        age: 25,
        position: 'Forward',
        image: 'jota.png'
    },
    {
        name: 'Luis Díaz',
        number: 23,
        age: 25,
        position: 'Forward',
        image: 'diaz.png'
    },
    {
        name: 'Jordan Henderson',
        number: 14,
        age: 32,
        position: 'Midfielder',
        image: 'henderson.png'
    },
    {
        name: 'Virgil van Dijk',
        number: 4,
        age: 31,
        position: 'Defender',
        image: 'dijk.png'
    },
    {
        name: 'Joël Matip',
        number: 32,
        age: 31,
        position: 'Defender',
        image: 'matip.png'
    },
    {
        name: 'Alisson Becker',
        number: 1,
        age: 30,
        position: 'Goalkeeper',
        image: 'alisson.png'
    },
    ];
// using JSON.stringify()
const jsonObj = JSON.stringify(playersArray);
// save to localStorage
localStorage.setItem("playersArray", jsonObj);
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css"
    rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi"
    crossorigin="anonymous">
    <title></title>
</head>

<body>
  <div class="container">
    <div class="col-xs-8 col-xs-offset-2 search-box">
      <div class="input-group">
        <input oninput="updateResult(this.value)" type="search" class="form-control" placeholder="Search..." />
      </div>
    </div>
    <div class="container">
      <div class="list-group result"></div>
    </div>
  </div>
</body>
<script defer type="module" src="./scripts/page2.js"></script>
</html>
import { playersArray as _playersArray } from './array.js';
let playersArray = _playersArray;
playersArray.map(data => console.log(data +1))


let resultList = document.querySelector(".result");

function updateResult(query) {
  if (query.length == 0) {
    resultList.innerHTML = "";
    return;
  }
  
  query = query.toLowerCase();

  let player = playersArray.filter(el => 
    el.name.toLowerCase().indexOf(query) != -1
    || el.number.toString().indexOf(query) != -1
    || el.age.toString().indexOf(query) != -1
    || el.position.toLowerCase().indexOf(query) != -1
    || el.image.toLowerCase().indexOf(query) != -1
  );
  resultList.innerHTML = "";
  player.forEach((data) => {
    resultList.innerHTML += `
      <div class="card list-group-item" style="width: 18rem;">
      <img class="card-img-top" src="images/${ data.image }" alt="Illustrasjon. Bildet av spiller.">
      <h4>${ data.name }</h4>
      <h5>Number: ${ data.number }</h5>
      <h5>Age: ${ data.age }</h5>
      <p>Position: ${ data.position }</p>
  </div>`;
  })
}

updateResult("")
maggyy
  • 5
  • 2
  • Hello maggyy, There is no need to use the defer attribute when loading a module script; modules are deferred automatically. Btw, please share the error log. – dineshpandikona Oct 13 '22 at 08:25
  • okei, but removing it dosent resolve the problem. Ive added the error code, coudnt add the error as a image, thats wierd – maggyy Oct 13 '22 at 09:06
  • please refer to this https://stackoverflow.com/questions/53630310/use-functions-defined-in-es6-module-directly-in-html for understanding why you are getting the error. In case, you dont have time to check it, add this "window.updateResult = updateResult" at the end of that JS file where updateResult is defined. – dineshpandikona Oct 13 '22 at 09:56

1 Answers1

0

Every module script has it's own scope, while non-module scripts and HTML all share the same window scope

So, if you are trying to make

<button onclick="click1()"> click me </button>
<script> function click1(){console.log('click1')} </script>

that will work, because click1 is in the same scope, but

<button onclick="click1()"> click me </button>
<-- well, modules can't be inlined, but for simplicity -->
<script type="module"> export function click1(){console.log('click1')} </script>

won't work, because click1 is now not in window scope

Either a) use non-module scripts. If you include multiple <script> tags, that would be mostly the same you want to achieve with imports b) add click1 to the window scope with window.click1 = click1 c) bind events prgrammatically with el.addEventListener('click', click1) d) use async import() to import in non-module scripts

Dimava
  • 7,654
  • 1
  • 9
  • 24