Error updating panel: data must be a mapping or None, not 'str'. Did you initialise all data binding sources before initialising this component?

What I’m trying to do:
Trying to to add items to a repeating panel
What I’ve tried and what’s not working:

Code Sample:

def update_anomaly_panel(self, anomaly):
      try:
          # Fetch anomaly details from the server
          anomaly_data = anvil.server.call('get_anomaly_details', anomaly)
          print(f"Fetched anomaly data: {anomaly_data}")  # Debugging output
          
          # Ensure that anomaly_data is valid and a dictionary
          if anomaly_data is None or not isinstance(anomaly_data, dict):
              print("Error: get_anomaly_details returned invalid data.")
              alert("Could not retrieve anomaly details.")
              return
          
          # Construct display data with expected structure
          display_data = {
              'Title': anomaly_data.get('Title', ''),
              'Content': anomaly_data.get('Content', ''),
              'Image': anomaly_data.get('Image')
          }
          
          # Get the current items in repeating_panel_anomalies, ensuring it's a list
          current_items = self.repeating_panel_anomalies.items or []
          
          # Ensure all items in current_items are dictionaries
          if not all(isinstance(item, dict) for item in current_items):
              print("Error: Found a non-dictionary item in current_items.")
              raise TypeError("All items in repeating_panel_anomalies.items must be dictionaries.")
          
          # Create an updated items list, ensuring each entry is a dictionary
          updated_items = current_items + [display_data]
          for item in updated_items:
              if not isinstance(item, dict):
                  print("Error: Found a non-dictionary in updated_items:", item)
                  raise TypeError("All items in updated_items must be dictionaries.")
          
          # Update the repeating panel items with validated data
          print('Before self.repeating_panel_anomalies.items = updated_items')
          self.repeating_panel_anomalies.items = updated_items
          print(f"Updated items list successfully: {updated_items}")  # Debugging output
      
      except Exception as e:
          print(f"Error updating panel: {str(e)}")
          alert(f"Error updating panel: {str(e)}") 
     

Error
when I get to this line:
self.repeating_panel_anomalies.items = updated_items

Error updating panel: data must be a mapping or None, not ‘str’. Did you initialise all data binding sources before initialising this component?

That sort of error normally happens during data binding on components in the repeating panel row template. Double check your data bindings for each component there to make sure they’re all valid.

Try removing the try-except block, so Anvil will manage the traceback and show more detailed info than your except block does.

You may get lucky and get a message that says which databinding is failing.

Thanks, all the setting are correct. for the biding,

* **Title Label**: `self.item['Title']`
* **Content Label**: `self.item['Content']`
* **Image Component**: `self.item['Image']`

Thanks @stefano.menci I tried that, but,

`TypeError: data must be a mapping or None, not 'str'. Did you initialise all data binding sources before initialising this component?`

* Error binding`data` of `rt_Content`to`self.item['Content']`:
`data must be a mapping or None, not 'str'`

This es a more inform error.

The thing is tha it is a rich text control and is getting markdown formated text.
Do you think this is the problem?

it looks like my Content is not binding well… but basically you are telling me that we should not place try-catch blocks?

thanks again,

I’m going to guess that you need to bind content instead of data (I’m digging in my memory, didn’t verify anything here).

The good developer handbook says you should always handle all exceptions. I don’t follow this rule. It’s just wrong.

Handling exceptions means doing something specific when something exceptional happens, ideally something exceptional that is identified by a specific exception type.

If all you are doing is showing a message for every exception, then it’s better to leave its handling to the framework, so it will help you during development.

When you know that a specific exception can happen, then you will add exception management for that specific exception.

I stop here, because my apps are used mostly by the employees in my company, and I absolutely want them to call me if they see an error, and I want to see that error logged in the app log.

If my apps were distributed more widely, perhaps I would add some generic exception handling to hide any ugly traceback from the end users, so they think that everything works just fine even if it doesn’t, and send myself some logging info (is this even legal? maybe it is after asking for consent?).

Hi @stefano.menci,

Thanks for the replay, it makes sense what you wrote, I have this type of exceptions to try and debug better, usualy I try to handle things, but I found out that eleminatin then anvil gave me a little bit more info, which is good.

I am new to anvil, I like it becase I am a AWS AI backend developer and dont have time to learn React and other frontend tools, at least for now.

was thinking that maybe I have to init things here in the ItemTemplate1Template???

from ._anvil_designer import ItemTemplate1Template
from anvil import *
import anvil.server
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables


class ItemTemplate1(ItemTemplate1Template):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)

    # Any code you write here will run before the form opens

Because of your suggestiong of getting rid of the try block I got a little more info about the error, and I asked ChatGPT, and gave me the solution.

# Construct display data with expected structure
display_data = {
'Title': anomaly_data.get('Title', ''),
 # Use a dictionary for Content to support RichText component binding
 'Content': {'text': anomaly_data.get('Content', '')},
 'Image': anomaly_data.get('Image')
  }

It needed to create a dictionary from the text. or :slight_smile:

The error indicates that the RichText component is still bound to data, which expects a dictionary, rather than to text, which can accept a simple string. Here’s how to address this properly:

  1. Ensure rt_Content is Bound to text Property, Not data:
  • Open ItemTemplate1 in the Anvil editor.
  • Select the RichText component (rt_Content) where you want to display Content.
  • In the Data Bindings panel, remove the data binding entirely.
  • Instead, bind the text property to self.item['Content'].
    by ChatGPT

Hmmm…
Your description doesn’t convince me.

RichText components don’t have a text property.

If I remember correctly, you assign a string with slots identified by curly braces to the content property, and a dictionary with the slot values to the data property.

You don’t describe how you setup the other properties, but I would say that one of these is true, and, judging by your previous posts, I’m going to assume that the first applies to you:

  1. You have already assigned (or used databinding) the string with its slots to content and you only need to assign a dictionary to data
  2. You need to assign both a string with slots to content and a dictionary to data
  3. You need to assign only a string without slots to content
1 Like

Hi there @stefano.menci,

I dont know but it worked for what chatGPT told me to do…

But, thanks for feedback, because I Was able to get more info about the problem and solve it.