Search code examples
javascriptreactjsfrontend

Search function works on desktop but doesn't on mobile browsers


I've solved the REST Countries API challenge from Frontend Mentors. I used React.JS, Bootstrap5, jQuery and Sass. After deploying to GitHub, the search function works well on desktop browsers, but failed to retrieve any results on mobile browsers.

I tried logging the search input value to the mobile browser console, and I found that it logged OK. But why it won't display the results in the UI -country names that have the same letters as search value- is beyond me. What can I do to make it run as it should on mobile browsers?

I tried it on Samsung Galaxy S22+.

The code relating to this function -I extracted it from the rest of the code-:

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

export default function Home() {
  let [countryList, setCountryList] = useState([])
  let [searchVal, setSearchval] = useState("")

  return (
    <input name='search' onChange={(e) => setSearchval(e.target.value)} className='form-control w-50 elements lightElementsBg' placeholder='Search for a country' />

    {countryList?.filter((country) => country.name.common.toLowerCase().includes(searchVal)).filter((country) => country.region.toLowerCase().includes(selectVal)).map((country, i) => {
      return (
        <div key={i} className="col-md-3 mt-5 land">
          <Link to={"/rest-countries-api-with-color-theme-switcher-master/details/" + country.cca3} className='elements text-decoration-none'>
            <div className='item lightElementsBg'>

              <img src={country.flags.png} alt="" className='w-100 imgs' />
              <div className='ms-3 w-100'>
                <h4 className='my-2'>{country.name.common}</h4>
              </div>
            </div>
          </Link>
        </div>
      )
    })}
  )
}

Thanks in advance :)


Solution

  • Your code seems to work fine both on desktop and phone on my end though

    But here are improvements I would suggest

    1. You used selectVal here, but I am guessing it should have been searchVal
      filter((country) => country.region.toLowerCase().includes(selectVal))
      filter((country) => country.region.toLowerCase().includes(searchVal))

    2. It is more efficient to combine the 2 filter methods into 1 to prevent unnecessary looping of such a large array. I combined them using the Logic OR ||
      countryList?.filter((country) => country.name.common.toLowerCase().includes(searchVal)).filter((country) => country.region.toLowerCase().includes(selectVal))
      countryList?.filter((country) => country.name.common.toLowerCase().includes(searchVal) || country.region.toLowerCase().includes(searchVal))

    3. For better filtering results, you should ensure that the strings being compared are in the same cases. You used toLowerCase() for the array values, but didn't do the same for the user's input.
      countryList?.filter((country) => country.name.common.toLowerCase().includes(searchVal) || country.region.toLowerCase().includes(searchVal))
      countryList?.filter((country) => country.name.common.toLowerCase().includes(searchVal.toLowerCase()) || country.region.toLowerCase().includes(searchVal.toLowerCase()))

    Updated Code

    import React, { useEffect, useState } from 'react';
    
    export default function Home() {
      let [countryList, setCountryList] = useState([])
      let [searchVal, setSearchval] = useState("")
    
      return (
        <input name='search' onChange={(e) => setSearchval(e.target.value)} className='form-control w-50 elements lightElementsBg' placeholder='Search for a country' />
    
        {countryList?.filter((country) => country.name.common.toLowerCase().includes(searchVal.toLowerCase()) || country.region.toLowerCase().includes(searchVal.toLowerCase())).map((country, i) => {
          return (
            <div key={i} className="col-md-3 mt-5 land">
              <Link to={"/rest-countries-api-with-color-theme-switcher-master/details/" + country.cca3} className='elements text-decoration-none'>
                <div className='item lightElementsBg'>
    
                  <img src={country.flags.png} alt="" className='w-100 imgs' />
                  <div className='ms-3 w-100'>
                    <h4 className='my-2'>{country.name.common}</h4>
                  </div>
                </div>
              </Link>
            </div>
          )
        })}
      )
    }