-2

I am implementing filter table in React Js, for this I need to search a product name entered by user from my product list. I am taking user input and finding it's index for each product of my product list using indexOf() function. If indexOf() return -1 then add this product to searched product list, otherwise ignore current product. I test it using an test component and it is working fine.

I went through following question, but it did't worked for me.

javascript indexOf keeps returning -1 even if the object is present

Node.js: indexOf returning -1 even though item is in array

Object comparison in javascript

indexOf method in an object array?

My testing component:

class App extends React.Component{
    render(){
        return(
            <div >
                <h1>Filter text: {this.props.filterText}</h1>
                <h2>Product name: {this.props.name}</h2>
                <h3>Test: {this.props.name.indexOf(this.props.filterText)}</h3>
            </div>
        )
    }
}

Input:

const filterText='r';
const name='ball';
ReactDOM.render(
  <App filterText={filterText} name={name} />,document.getElementById('hello')
);

Output:
Output 1 Input:

const filterText='l'; 
const name='ball';
ReactDOM.render(
  <App filterText={filterText} name={name} />,document.getElementById('hello')
);

Output:
enter image description here

Same functionality i want to include in my react filter list project. When the same input i am giving then it is returning -1. For simplicity, i rendered all the values on screen.
My Code:(Component that have logic.


 class ProductTable extends React.Component{
    constructor(props){
        super(props);
    }
    render(){
        var filterText=this.props.filterText;
        const inStockOnly=this.props.inStockOnly; 
        const row=[];
        let lastCategory=null;
        this.props.product.forEach(function(product){
            row.push(
                <Test filterText={filterText} name={product.name} test={product.name.indexOf(filterText)} />
            );
            if(product.name.indexOf(filterText)===false)
                return;

            if(inStockOnly&&!product.stocked)
                return;

            if(product.category!==lastCategory){
                row.push(
                    <ProductCategoryRow category={product.category} key={product.category}/>
                );
            }
          row.push(
              <ProductRow product={product} key={product.name}/>
          );
          lastCategory=product.category; 
        })

        return(
            <div>
        <h3 className="text-danger">Your Product</h3>
            <ProductCategoryRow category={row}/>
            </div>
        );
    }
}

Other component:


class ProductCategoryRow extends React.Component{
    render(){
        const category=this.props.category;
        return(
            <tr>
                <th colSpan='2' className="text-info">
                    <h1>{category}</h1>
                </th>
            </tr>
        )
    }
}
class ProductRow extends React.Component{
    render(){
        const product=this.props.product;
        const name=product.stocked? product.name: <span style={{color:'red'}}>
            {product.name}
        </span>
        return(
                <tr className='text-warning'>
                     <td><h4>{name}</h4></td>
                     <td> <h4>{product.price}</h4> </td>
                </tr>

        );
    }
}

Test is index of filterText OUTPUT:
Incorrect:
enter image description here
Correct:
enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • `'b' !== 'B'`. Maybe lowercasing the strings first would help? `name.toLowerCase().indexOf(filter.toLowerCase())` – Emile Bergeron May 08 '20 at 05:57
  • 1
    You provided very extensive and even a little of non-relevant content. Your problem is visible in the pictures though. I did not have a look at the code at all. Consider putting the product name and the query string toLowerCase() as "Ball" is capital "B" and lowercase b is not equal. Actually the difference is 32 thus a comparison would return false. – jPO May 08 '20 at 06:12

2 Answers2

1

The indexOf() method is case-sensitive, that's why you got these results, check the documentation. You can use the .toLowerCase() or the .toUpperCase() function before check with indexOf(). You need to use any of them on both of the strings you test.

For example with .toLowerCase(), change your code to:

test={product.name.toLowerCase().indexOf(filterText.toLowerCase())}

And

if(product.name.toLowerCase().indexOf(filterText.toLowerCase())===false)
Tamas Szoke
  • 5,426
  • 4
  • 24
  • 39
  • As you can see my input is already in lower case. But, as you said i replaced `` to `` and stil having same problem . –  May 08 '20 at 06:02
  • Oh, I mean the name should be lowercase too, editing my answer. – Tamas Szoke May 08 '20 at 06:04
  • I think before matching convert `filterText` and `product.name` to either lower or uppercase – Rahul May 08 '20 at 06:09
-1

You can Try to use includes method in lodash library. This should work.

_.includes(product.name.toLowerCase(), filter.toLowerCase());