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);
–
–
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.