Home > OS >  Reactjs, typescript
Reactjs, typescript

Time:05-11

I am trying to make Searchbar where I can fetch the authors and show the author Id and picture, Why I'm getting this error (any Property 'toLowerCase' does not exist on type 'never') in my code?

import { useEffect, useState } from 'react';
import axios from 'axios';

function Searchbar() {
  const [query, setQuery] = useState('');
  const [data, setData] = useState([]);

  // Add one more state to store the authors being searched for

  const [searchResults, setSearchResults] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await axios.get(`https://picsum.photos/v2/list`);
      setData(res.data);
    };
    fetchData();
  }, []);

  useEffect(() => {
    setSearchResults(
      data.filter((authorData) =>
        authorData['author'].toLowerCase().includes(query)
      )
    );
  }, [query, data]);

  return (
    <div className='app'>
      <input
        className='search'
        placeholder='Search...'
        onChange={(e) => setQuery(e.target.value.toLowerCase())}
      />
      <div>
        {searchResults.map((author) => (
          <div>{author}</div>
        ))}
      </div>
    </div>
  );
}

export default Searchbar;

CodePudding user response:

The problem seems to be you are relying on typescript to infer types of an api call. (Instead typescript inferred it as never which would always error if you try anything with it)

To fix this, simply set a type for the fetch data

type fetchData = {
  id: number,
  author: string,
  width: number,
  height: number,
  url: string,
  download_url: string
}

Then set your states as such

const [data, setData] = useState<fetchData[]>([]);
const [searchResults, setSearchResults] = useState<fetchData[]>([]);

Full code

import { useEffect, useState } from "react";
import axios from "axios";

type fetchData = {
  id: number,
  author: string,
  width: number,
  height: number,
  url: string,
  download_url: string
}

function Searchbar() {
  const [query, setQuery] = useState("");

  const [data, setData] = useState<fetchData[]>([]);

  // Add one more state to store the authors being searched for

  const [searchResults, setSearchResults] = useState<fetchData[]>([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await axios.get(`https://picsum.photos/v2/list`);
      setData(res.data);
    };
    fetchData();
  }, []);

  useEffect(() => {
    setSearchResults(
      data.filter((authorData : fetchData) =>
        authorData.author.toLowerCase().includes(query)
      )
    );
  }, [query, data]);

  return (
    <div className="app">
      <input
        className="search"
        placeholder="Search..."
        onChange={(e) => setQuery(e.target.value.toLowerCase())}
      />
      <div>
        {searchResults.map((author) => (
          <div key={author.id}>{author.author}</div>
        ))}
      </div>
    </div>
  );
}

export default Searchbar;
  • Related