Using the Search Hints component with a List instead of a Table

Hi,

I’ve copied the Search Hints app and added it as a dependency to my app, however I don’t want the results to populate based on a Table, but rather from a column I pull from a Google Sheet and then store in a list.

I haven’t changed the __init__ function of the form from the example code, other than calling the get_search_keys() from a Module rather than server code:

    # The SearchHints instance has an event called x-get-search-keys that gets called to retrieve the search keys.
    self.search_hints_1.set_event_handler('x-get-search-keys', self.get_search_keys)

    # The SearchHints instance has an event called x-search-hints-result that gets called
    # when the result has been selected.
    self.search_hints_1.set_event_handler('x-search-hints-result', self.update_result_label)

  def update_result_label(self, result, **event_args):
    """Set the result label on this Form to the selected search result."""
    self.label_result.text = result

  def get_search_keys(self, **event_args):
    """Get the search keys from the Data Table."""
    return Module1.get_search_keys()

In my Module1 I have the following:

def get_search_keys():
  """Get the keys to populate the Search Hints."""
  keysList = list(map(int, apartmentsDict.keys()))
  return keysList

I used list(map(int, apartmentsDict.keys())) because when I had
keysList = list(apartmentsDict.keys())
I got the error:

TypeError: string indices must be integers, not str

so I assumed I had to convert my array to integers. However when I did that, now I get the error

TypeError: 'int' does not support indexing

I am returning an iterable list, so why do I get this error?

(I’m going off topic…) I have two comments:

  • Here it sounds like you are using a dictionary where keys are integers. There may be legitimate reasons to do that, but more often there are better ways to approach the problem.
  • The map works, but I would use a more pythonic and readable way:
   keys_list = [int(k) for k in apartmentsDict.keys()]

(Back on topic…) Without seeing the failing code or the full error message, my guess is that this error is not caused by the content of the list being strings rather than integers, but by some other part of the code that is trying to use a string rather than an integer to access an item of a list.

Can you show the falling line of code and the full error message, including the stack?

I am using a dictionary where keys are integers, however they are stored as strings in the dictionary. Actually I have no practical reason to convert them to int, but since I received the string indices must be integers, not str error, I assumed I had to convert them to int.

Unfortunately I don’t know how to access the failing line of code. Here is the full error message:

TypeError: 'int' does not support indexing
at app/SearchHints/SearchHints.py:42
called from app/SearchHints/SearchHints.py:25

Maybe I need to use the Uplink and git clone the entire project locally to see those additional files?

I don’t understand what uplink or cloning or project you are talking about…

What is at line 42 of SearchHints.py?

That’s where SearchHints.py line 42 will be. Open the dependency app, not your main app, and see what code is at that line.

1 Like
      self.repeating_panel_results.items = sorted([
        key['entry'] for key in self.search_keys
        if key['entry'].lower().startswith(text.lower())
      ])

It is expecting a list of dictionaries with key “entry”. I have modified my code like so to make 1-value dictionaries of every value in the list with key “entry”. I’m sure this isn’t the best way, but it works.

  #first convert the keys of the dictionary into a list, then into a list of dicts with key "entry"
  keysList = list(apartmentsDict.keys())
  my_dict_list = [{'entry': value} for value in keysList]
  return my_dict_list

I also modified the SearchHints app to change the value of the input textbox to populate with the value the user clicks in the “Hints” dropdown. It might be a useful modification to the app for others.

Try to print(self.search_keys) before that line and see what you get.

I get output like

[{'entry': '1101'}, {'entry': '1102'}, {'entry': '1103'},

And that is what the function at line 42 of SearchHints.py wants as input. So it is working now.
I also updated SearchHints.py as stated above which is more intuitive to me than the previous implementation.

Can you print something after this?

This code works just fine:

search_keys = [{'entry': '1101'}, {'entry': '1102'}, {'entry': '1103'}]
sorted([
        key['entry'] for key in search_keys
        if key['entry'].lower().startswith('1'.lower())
      ])
>>> ['1101', '1102', '1103']

(And it would work without creating the list, by passing the iterable to the sort function, something like sorted(key['entry'] for ...), but that’s another story.