Having trouble creating a (string) filter for a search engine with Google's Api using (Jsx, React)

55 views Asked by At

Hey everyone I am new to coding and I am currently trying to get my app to work with a checkbox(string) filter.

Code Link : https://codesandbox.io/s/fervent-wilbur-yb9ur6

This is a picture of the code. image of code

So the API works but the filter on the right does not work.

I want the user to search for something on the search box. Then use the filters/checkbox on the right side to filter out what words he wants to search, instead of searching for the full sentence. So the selected checkbox will update the search box in order to create a refined search result.

Searchview.jsx

import React from 'react'
import { useSelector } from 'react-redux'
function SearchResults() {
  const { query } = useSelector((state) => state.query)
  let str = query.join('+')

  
  return (
    <div style={search}>
      <iframe
        width={'100%'}
        height={'100%'}
        src={`https://www.google.com/search?igu=1&q=${str}`}
      ></iframe>
    </div>
  )
}

const search = {
  height: '100%',
}

export default SearchResults

Term.jsx

import { useState, useEffect } from 'react'
import {
  LinearProgress,
  Checkbox,
  ListItemIcon,
  ListItemButton,
  ListItem,
  ListItemText,
  Divider,
} from '@mui/material'
import { useSelector, useDispatch } from 'react-redux'
import { setExpansion, setQuery } from '../app/querySlice'

function Term({ term, isChecked }) {
  const dispatch = useDispatch()

  const [checked, setChecked] = useState(isChecked)
  const { query, expansion } = useSelector((state) => state.query)

  useEffect(() => {
    if (checked) {
      console.log('checked: ' + term)
    } else {
      console.log('not checked: ' + term)
    }
  }, [term, checked])

  return (
    <>
      <ListItem disablePadding>
        <ListItemButton dense onClick={() => setChecked(!checked)}>
          <ListItemIcon>
            <Checkbox edge='start' checked={checked} disableRipple />
          </ListItemIcon>
          <ListItemText primary={`${term}`} />
        </ListItemButton>
      </ListItem>
      <LinearProgress variant='determinate' color='secondary' value={60} />
      <Divider />
    </>
  )
}

export default Term

Terms.jsx

import React, { useEffect } from 'react'
import Term from './Term'
import { List } from '@mui/material'
import { useSelector, useDispatch } from 'react-redux'
import { setExpansion, setQuery } from '../app/querySlice'

function Terms() {
  const dispatch = useDispatch()
  const { query, expansion } = useSelector((state) => state.query)

  useEffect(() => {
    dispatch(setQuery(query))
    dispatch(setExpansion(expansion))
  }, [query, expansion, dispatch])

  return (
    <div style={termsStyle}>
      <List>
        {query[0] !== '' ? (
          <div>
            {query.map((term, index) => (
              <Term key={index} term={term} isChecked={true} />
            ))}
            {expansion.map((term, index) => (
              <Term key={index} term={term} isChecked={false} />
            ))}
          </div>
        ) : (
          <p>No terms</p>
        )}
      </List>
    </div>
  )
}

const termsStyle = {
  height: '100%',
  overflowY: 'scroll',
}

export default Terms

querySlice.js

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  query: [''],
  expansion: ['expansion1', 'expansion2', 'expansion3'],
}

export const querySlice = createSlice({
  name: 'query',
  initialState,
  reducers: {
    reset: (state) => initialState,
    setQuery: (state, action) => {
      state.query = action.payload
    },
    setExpansion: (state, action) => {
      state.expansion = action.payload
    },
  },
})

export const { reset, setQuery, setExpansion } = querySlice.actions
export default querySlice.reducer

store.js

import { configureStore } from '@reduxjs/toolkit'
import queryReducer from './querySlice'

export const store = configureStore({
  reducer: {
    query: queryReducer,
  },
})

1

There are 1 answers

2
Meeoh On

It seems like you have some redux state that holds the value of query. Then you're looping over all the words in the query and making a check box for each one.

It seems like one approach you can take is the following:

When a checkbox is unchecked, then modify the query value in your redux store such that it no longer contains the word associated with that checkbox.

However, you can imagine that when you do that, the checkbox will go away as well. So you could consider modifying your redux state to look something like:

{
  query: [{value: 'joshua', checked: true}, {value: 'was', checked: true}, {value: 'here', checked: true}
}

As well as that, instead of looking up the word that they have unchecked/checked, you can also look it up based on the index. The edge case that protects against is when your query is something like "joshua was here joshua". If you're just looking for the first term that matches what was unchecked, if you uncheck the last "joshua", the first one will get removed. Whereas if you do your lookup by index, then you can find the right one everytime.