Primefaces autocomplete showcase selects wrong Country Object

Viewed 63

In order to built a ZIP-code (PostCode: Ned) autocompleter I started investigating Primefaces Country autocomplete and found a bug in the CountryService.java component. As a result CountryConverter returns a wrong Country Object.

This is CountryService.java code fragment that causes the issue:

countries = new ArrayList<>();

for (int i = 0; i < locales.length; i++) {
            Locale country = new Locale("", locales[i]);
            countries.add(new Country(i, country.getDisplayCountry(), country.getCountry().toLowerCase()));
        }
        
        Collections.sort(countries, (Country c1, Country c2) -> c1.getName().compareTo(c2.getName()));

The countries (array-list) get its country.Id's numbered from 0 to locales.length within the for-loop. But then it is being sorted by country.getName(). As so, all Country objects will get another index within the countries list.

However, this is what de CountryConverter is doing when the user chooses a country from the country pulldownlist (of p:autocomplete):

    @Override
    public Country getAsObject(FacesContext context, UIComponent component, String value) {
       ......
            return countryService.getCountries().get(Integer.parseInt(value));
       ......
    }

Which returns a wrong Country Object because the originally assigned number(Id) is not the same as the array instances (hard)index anymore due to the sort of the countries list.

I took this example to start with and in my own application it led to wrong Zip-code objects returned. As I was not familiar yet whith Primefaces-autocomplete component (which I find a very nice thing!), I first thought there went something wrong in my own interpreted code. And took me some time to find the real cause.

I built in this workaround:

        Collections.sort(countries, (Country c1, Country c2) -> c1.getName().compareTo(c2.getName()));
        .....

        int n = 0;
        for (Country ctry : countries) {
            ctry.setId(n);
            n++;
        }

Maybe Primefaces could correct the example and will my experience help others to implement p:autocomplete quicker than I did!?

1 Answers
Related