Search not working

What I’m trying to do:
return text back from a table and displaying in a repeating panel. the code i am using works in my other app but not here.
What I’ve tried and what’s not working:
Here is the error message i get back.
TypeError: argument of type 'NoneType' is not iterable

  • at order_service, line 44

Code Sample:

# this is a formatted code snippet.
# paste your code between ``` 
@anvil.server.callable
def search_Inventory(query):
  result = app_tables.inventory.search()
  if query is not None:
    result = [
      x for x in result
      if query in x['Description']
      or query in x['Item number']
    ]
  return result


**Clone link:**
*share a copy of your app*

Welcome to the forum!

Either x['Description'] or x['Item number'] is None, generating the error.

You really should be using the query operators for this, to put the work onto the database and make it so you don’t need to iterate through the entire set of inventory items every time. Look for the q.like and q.ilike sections: Querying Data Tables

1 Like

Thank you for the info I will try it and let you know how it goes. This is my first time ever coding and it has been a crazy and fun time. I have been really struggling with a couple of things, but it has been great when I get something right. I figure to tackle one problem at a time.

Anvil’s a good first platform, but there is definitely a learning curve. Just ask back when you run into trouble.

Thank you sir. I will be reaching out.

I have been trying to use those examples that you sent, but I don’t seem to have any luck. what i am trying to do is when I put text into a textbox and hit enter it will generate everything in the data table that matches the text. or anything close to the text. ie: type in the word basic and it populates the list with anything that is close to that word. or like 1101 and i gives me anything with 1101*** .

What code are you using?

this is the link to my app. if you open up order_form you will see it.

You are doing the search via a server call:

anvil.server.call('search_Inventory', self.text_box_search.text)

But not doing anything with what the server call returns. You have to put the return from the server call back into the repeating panel’s items property.

How? Like I said this is all new to me. It would be great if I had some reference like a list or a break down of the different commands. I have looked over alot of stuff to get this far. Could you please help.

Look on line 20 in your OrderForm. That’s where you set the repeating panel’s items property to the original search.

Ok lets correct some things. You don’t want to pass ‘query’ text to your function. It will only search for ‘query’ all the time not your text from the box.
2nd - what jshaffstall mentioned already. You need to pass your values from the query back to your panel.

I will add unnecessary variables just to show you how it works. you could use the self.textbox.text and pass your query directly to your panel.items

  def search_button_click(self, **event_args):
    description_name = self.text_box_search.text#you need to assign your description name value first
    matched_results = anvil.server.call('search_Inventory', description_name)#instead of passing description_name you could pass self.text_box_search.text but don't forget to change it on server side
    self.repeating_panel_1.items = matched_results#assign found rows to your repeating panel
    pass  

It get’s much easier with the time spend with Anvil :slight_smile: . It took me too a while and patient forum users to learn it.

Thanks I will give it a try. Appreciate the help.

it has been a while. i am still having problems with the search. this driving me nuts. so i display all the items in the table. i have a text box to input the name or a item number to search then the flow panel that shows the items that were found in the data table. i stopped working on this for a bit and finished what i could with the rest. now i am back to this. please help.

Some example for you:

Server side: a function that work with 2 text boxes on client side and query the database.

  • 2 variables: qacn - text form 1st textbox and qshort from 2nd textbox.
  • It’s a “contains” case insensitive query.
  • q.fetch_only is worth using if your data table contain more columns than you want to show. It’s good for the perfomance.
@anvil.server.callable
def acn_quick_filter(qacn,qshort):
  """quick filter via ACN, Assay Databank form"""
  return app_tables.assay_databank.search(q.fetch_only("name_long", "name_short","application_code","matrix","indication"),
        application_code=q.ilike('%{}%'.format(qacn)),
        name_short=q.ilike('%{}%'.format(qshort))
  )

Client Side: 2 textboxes
image

in properties of each textbox please set up how you want the user to interact with it or create a button to fire the search:

I’m using autocomplete from Anvil Extras so the properties options are not the same.
image

That’s the code controlling the search: I’m using str() to make sure the number will be string, because my search is a text query for a text database column.

  def autocomplete_acn_pressed_enter(self, **event_args):
    """quick filter auto search in database and footer update"""
    database = anvil.server.call(
      'acn_quick_filter',
      qacn = str(self.autocomplete_acn.text), qshort = str(self.autocomplete_short.text)
    )
    self.repeating_panel_assay.items = database

I hope it will help now. If you are looking for different query options, please use: this tutorial

I have 1 text box with a press enter event. I call the sever code with it. The flow panel on the page is showing all items right now. I use self.flow_panel_1.items = anvil.server.call(‘get_items’) to get the items into the flow panel. Then if I type in a name or an item number in the search box it should display anything matching that in the database. It doesn’t.
I call this when press enter in the search box.
anvil.server.call(‘search_items’, self.search_box.text). In my server if I change return to print it gives me a message in the output "live object. But if I change back to return it doesn’t change the flow panel returned items.

On the server you are doing:

matching_items = inventory_table.search()

That will give you all the items in the table. You should read the docs on narrowing your search to only given items based on a field (Anvil Docs | Using Data Tables from Python) or if you need partial text searches look at the query operators (Querying Data Tables).

1 Like

I agree. The database can filter rows much faster than Python can.

Please read the docs or examine my example. I’m using 2 text boxes. just remove one and make everything match your example. It’s querying for everything case insensetive that contain some part of text:
q.ilike('%{}%'.format(your_text_box_search))

Please don’t call search that way. You should make your code more readable. Assing it first to variable then pass the variable to server side

text_query = self.search_box.text

found_rows = anvil.server.call(‘search_items’, text_query )
self.flow_panel_1.items = found_rows

Thanks I will try that. I found that if I change from a flow panel to a repeating panel my code works! I will try this with the flow panel. It looks nicer the a repeating panel.