添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

So first of all, I'm working with a JSON but I can't seem to put it here in my snippet so I'll just explain what I'm trying to do:

When you load the page it shows a collection of 5 phones and it has a validation form with a select and a submit. In the select there are options with the unique brands of the phones. If I select 'iPhone' for example i only want the phones with the brand 'iPhone' to show.

Everything works untill now but if i try to filter the list i get an error 'Cannot read property filter of undefined', i suppose because i return null but i can't seem to figure out the solution. I did some research and saw this question was already asked multiple times but i still can't find how to do it myself in this code of mine.

Any help would be useful thanks!

I am working with es6 btw:

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();
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;
  display: flex;
  flex-direction: column;
  padding-left: 3rem;
  padding-right: 3rem;
  border-bottom: .1rem solid black;
  padding-right: 1rem;
  padding-left: 1rem;
  margin-bottom: 3rem;
  margin-bottom: 1rem;
  height: 100%;
  width: 100%;
  font-family: sans-serif;
  margin-left: 1rem;
  font-size: 1.3rem;
  margin-left: 1rem;
select{
  margin-bottom: 2rem;
<!DOCTYPE html>
<html lang="en" dir="ltr">
    <meta charset="utf-8">
    <title></title>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/style.css">
  </head>
    <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>

There is some moment where phones is undefined so you have to set an empty array as its default value when you call array.prototype.filter.

So try to change this:

phones.filter(phone => phone.brand == brand);
(phones || []).filter(phone => phone.brand == brand);
                Now when I submit the form i get this array: undefined:1 GET 127.0.0.1:59401/undefined 404 (Not Found)
– Robbe Verhoest
                May 9, 2018 at 9:19
                Is it because my form submits to a page that doesn't exist? But that would be weird because there is a preventdefault on it?
– Robbe Verhoest
                May 9, 2018 at 9:24

I looks like you are instantiating the phones variable on the fist line, but you are never assigning a value to it, so it will always be equal to undefined.

Check where you are getting the data for phones and make sure you are assigning it to the phones variable.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.