无法读取未定义错误的属性“过滤器”

Rob*_*est 1 javascript ecmascript-6

首先,我正在使用 JSON,但我似乎无法将它放在我的代码片段中,所以我只是解释一下我想要做什么:

当您加载页面时,它会显示 5 部手机的集合,并且有一个带有选择和提交的验证表单。在选择中,有具有独特手机品牌的选项。例如,如果我选择“iPhone”,我只希望显示品牌为“iPhone”的手机。

到目前为止一切正常,但如果我尝试过滤列表,我会收到错误“无法读取未定义的属性过滤器”,我想是因为我返回 null 但我似乎无法找出解决方案。我做了一些研究,发现这个问题已经被问过多次,但我仍然找不到如何在我的这段代码中自己做到这一点。

任何帮助都会很有用,谢谢!

顺便说一句,我正在使用 es6:

{
  let phones;

  const initValidation = () => {
    const $form = document.querySelector(`form`);
    $form.noValidate = true;
    $form.addEventListener(`submit`, handleSubmitForm);
  }

  const handleSubmitForm = e => {
    const $form = e.target;
    e.preventDefault();
    if($form.checkValidity()){
      const filteredPhones = getFilteredPhones();
      createPhone(filteredPhones);
    }
  };

  const getFilteredPhones = () => {
    const brand = document.querySelector(`.brands`).value;
    return phones.filter(phone => phone.brand == brand);
  };

  const setBrandOptions = brands => {
    const $select = document.querySelector(`.brands`);
    brands.sort().forEach(brand => {
      const $option = document.createElement(`option`);
      $option.value = brand;
      $option.textContent = brand;
      $select.appendChild($option);
    });
  };

  const getUniqueBrands = phones => {
    const uniqueBrands = [];
    // for (let i = 0; i < phones.length; i++) {
    //   if (!uniqueBrands.includes(phones[i].brand)){
    //     uniqueBrands.push(phones[i].brand);
    //     console.log(phones[i].brand);
    //   }
    // }
    phones.forEach(phone => {
      if(!uniqueBrands.includes(phone.brand)){
        uniqueBrands.push(phone.brand);
        console.log(phone.brand);
      }
    });
    return uniqueBrands;
  };


  const createPhone = phones => {
    const $div = document.createElement(`div`);
    document.querySelector(`section`).appendChild($div);

    const $img = document.createElement(`img`);
    $img.setAttribute('src', phones.image);
    $div.appendChild($img);

    const $title = document.createElement(`h2`);
    $title.textContent = phones.name;
    $div.appendChild($title);

    const $ul = document.createElement(`ul`);
    $div.appendChild($ul);
    $librand = document.createElement(`li`);
    $librand.textContent = phones.brand;
    $ul.appendChild($librand);
    $liyear = document.createElement(`li`);
    $liyear.textContent = phones.year;
    $ul.appendChild($liyear);
  };

  const parseJSON = phones => {
    console.log(phones);
    phones.forEach(phone => createPhone(phone));
    const brands = getUniqueBrands(phones);
    setBrandOptions(brands);
  };

  const initJSON = () => {
    const url = "assets/data/phones.json";
    fetch(url)
      .then(r => r.json())
      .then(jsonObject => parseJSON(jsonObject));
  };

  const init = () => {
    initJSON();
    initValidation();
  };

  init();
}
Run Code Online (Sandbox Code Playgroud)
body{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
section{
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: flex-end;
}
div{
  display: flex;
  flex-direction: column;
  padding-left: 3rem;
  padding-right: 3rem;
}
h1{
  border-bottom: .1rem solid black;
  padding-right: 1rem;
  padding-left: 1rem;
  margin-bottom: 3rem;
}
img{
  margin-bottom: 1rem;
  height: 100%;
  width: 100%;
}
h2{
  font-family: sans-serif;
  margin-left: 1rem;
  font-size: 1.3rem;
}
ul{
  margin-left: 1rem;
}
select{
  margin-bottom: 2rem;
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <h1>My Phone Collection</h1>
    <form action="">
			<label for="brands">Brand:
			<select id="brands" class="brands input">
        <option value="All">All</option>
      </select>
			<span class="error"></span>
			</label>

			<button type="submit">Search</button>
	</form>
    <section></section>
    <script type="text/javascript" src="js/script.js"></script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

Fal*_*aly 5

有时 是phones未定义的,因此您在调用时必须设置一个空数组作为其默认值array.prototype.filter

所以尝试改变这一点:

phones.filter(phone => phone.brand == brand);
Run Code Online (Sandbox Code Playgroud)

到:

(phones || []).filter(phone => phone.brand == brand);
Run Code Online (Sandbox Code Playgroud)