DEV Community

dreplica
dreplica

Posted on • Updated on

Search component using Typescript, React, Express, PostgresQl

Am Sure you've come across that search component that made things bad for you.

prerequisite: React, Typescript, Express

I would make it very short and simple.

Suppose you've been trying to create a search component that is to render on user keypress 'fetching data from the server and giving it back to the component that needs it immediately'

first we would create a server side to get all post request from a user using req.params, am using a controller to route style here.

router.post('/search/:id', async (req: (user & Request), res:Response) => {
const person:{search?:string[],error?:string}= await Search(req?.user as string, req.params['id'])
//returns the search data 

return person?.search ?
        res.status(200).json(person) :
        res.status(404).json(person)
     })

i know we've climbed a serious mountain but just one more backend to complete our search task, as you can see am using authenticate as a middleware there, so we can have a bit of security attached, also you can add joi validation and other forces of defence the imperial leaders deem fit.

next is the main search plate, am using postgres node-pg-migrate and @databases/pg.

export const Search = async (token:string,args:string)=>{

 try {
   if(!token){
   return {error:'network error please try again'}
      }

   const search = await db.query(sql`select * from items where 
        lower(itemname) like ${args+'%'} `)
   return {search:search} 

   } catch (error) {
        return {error:error.message}
      }
 }

here am converting all itemname to lowercase so my search from the frontend can be accessed, used like a Regexp

so now we run yarn start to test it, you can stop reading from here if this is all you wantend, try using postman to test your endpoint and see if the search is going through from your SQL table.

FRONT END SIDE.

import React,{useState, useEffect, ChangeEvent} from 'react'; 

function Searcher():React.FC =>{

    const [search, setSearch] = useState("")

    const handleSearch = (e:ChangeEvent<HTMLInputElement>) =>{

       e.preventDefault();
       setSearch(e.currentTarget?.value)
        }
   return (
<div>
   <input type="text" value={search} onChange={getSearch}/>
   <SearchComponent text={state} />
</div>);
}
function SearchComponent({text}):React.FC<{text:string}>{
   const [state,setstate] = useState<string[]>([])

   useEffect(()=>{
         getQuery(text)
    },[text])

   const getQuery = async (text:string)=>{
         const data = await fetch(`...api/${text}`)
         setstate(data.json())
    }

return(
<ul>
  {
state.map((item:string,index:number)=><li key={index}>{item}</li>)
}
</ul>)
}

thats all for now, easy pizzy. you just have to understand how to manage the state on every change and you're good to go. We are creating a seperate component to manage the fetch so it doesnt disrupt the app when rerendering, it would act as an individual component that act on change to the parent component to render a list of the search input

Top comments (0)