Home > Mobile >  Filter is not a function in React JS
Filter is not a function in React JS

Time:01-12

I am doing filter the data which comes from API but I am stuck at filter the data.

here is my filter.js file

import React from 'react'

  const Filter = ({
  searchInput,
  setSearchInput,
  photos,
  setFiltered
  }) => {

const handleSubmit = (e) =>{
    e.preventDefault();
}

const searchPhotos = (searchValue) =>{
    setSearchInput(searchValue)

if(searchInput) {
    const filterPhotos = photos.filter((photo)=>
        Object.values(photo)
        .join("")
        .toLowerCase()
        .includes(searchValue.toLowerCase())
    )
    setFiltered(filterPhotos)
} else {
    setFiltered(photos)
}
}
  return (
    <>
      <section className='filter'>
            <form className='form-control' onSubmit={handleSubmit}>
                <input type="search" 
                name="search" 
                id="search" 
                autoComplete='off' 
                placeholder='Search Photos'
                onChange={(e)=> searchPhotos(e.target.value)}  
                />
            </form>
        </section>
    </>
)
}
export default Filter

here is photos.jsx file

(where I supposed to filter the data comes from API). On load data comes perfectly via API search query but when I type on search box it will shows error. Uncaught TypeError: photos.filter is not a function

import React, { useEffect, useState } from 'react';
import Filter from './Filter';

const url = 'https://api.pexels.com/v1/search?query=Nature'

const Photos = () => {

const [photos, setPhotos] = useState([]);
const [filtered, setFiltered] = useState([]);
const [searchInput, setSearchInput] = useState("");
const [isLoading, setIsLoading] = useState(true)

useEffect(()=>{
    const fetchPhotos = async () =>{
        const res = await fetch((url),{
            headers: {
                Authorization: 'MY_API_KEY'
            }
        })
        const photos = await res.json()
        setPhotos(photos)
        setIsLoading(false)
    }

    fetchPhotos()
},[])
return (
   <>
        <Filter
            searchInput={searchInput}
            setSearchInput={setSearchInput}
            setFiltered={setFiltered}
            setPhotos={setPhotos}
            photos={photos}
        />

        { 
            isLoading ? (
                <h1 className='loading'>Loading...</h1>
            ) : searchInput.length > 1 ? (
                <section className="countries">
        {
            filtered.photos.map((photo,index)=>{
            return(
                <article  key={index}>
                <div className="flag">
                  <img src={photo.src.original} alt={photo.photographer} />
                </div>
                <div className="details">
                  <h4 className="country-name">
                    Photographer Name: <span>{photo.photographer}</span>
                  </h4>
                </div>
              </article>
            )
        })}
                </section>
            ) : (
                <section className="countries">
                    {
                        photos.photos.map((p, index) =>{
                            const {photos, src} = p

                return(
                            <article key={index}>
                            <div className="flag">
                                <img src={p.src.original} alt={p.photographer} />
                            </div>
                            <div className="details">
                            <h4 className="country-name">
                                Photographer Name: <span>{p.photographer}</span>
                            </h4>
                            </div>
                        </article>
                    )
                        })
                    }
                </section>
            )
        }

        
   </>
)
}
export default Photos

API Data is

{
"page": 1,
"per_page": 15,
"photos": [
    {
        "id": 15286,
        "width": 2500,
        "height": 1667,
        "url": "https://www.pexels.com/photo/person-walking-between-green-forest-trees-15286/",
        "photographer": "Luis del Río",
        "photographer_url": "https://www.pexels.com/@luisdelrio",
        "photographer_id": 1081,
        "avg_color": "#283419",
        "src": {
            "original": "https://images.pexels.com/photos/15286/pexels-photo.jpg",
            "large2x": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
            "large": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=650&w=940",
            "medium": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350",
            "small": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=130",
            "portrait": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&fit=crop&h=1200&w=800",
            "landscape": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&fit=crop&h=627&w=1200",
            "tiny": "https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&fit=crop&h=200&w=280"
        },
        "liked": false,
        "alt": "Person Walking Between Green Forest Trees"
    },
    }
    ]

CodePudding user response:

Notice the API data has a key photos, which actually contains your data. So what you should do is photos = (await res.json()).photos and then setPhotos(photos)

CodePudding user response:

First thing I noticed incorrect is you're using useState for photos const [photos, setPhotos] = useState([]); and then you've tried to create a new const variable called photos here:

const photos = await res.json()
setPhotos(photos)

Change that to this:

setPhotos(await res.json())

The second thing incorrect is you aren't assigning the key photos from the JSON to the variable photos, you are assigning the whole JSON object.

Next thing you should do is change this:

setPhotos(await res.json())

To this:

setPhotos(await res.json().photos)
  •  Tags:  
  • Related