Problem asigning loaded image to image component using code


I have several UI components created by code. This works fine.
Among those I have a fileloader and an image.
On the fileloader_change event I want to change the image in the image component by the one loaded in the file loader.

Here is the code for the event handler: (you will see many comment, mostly for debuggin purposes, and some for failed attempts to achieve the goal)

  def handle_fileloader_change(self, sender, key, file, files, event_name,image_name, **event_args):
      print("These are properties of the fileloader")
      #print("Self Input - Image Loader : ----", self.inputs)
      print("File:- ----", file)  # This should be the current file loaded when the event is triggered
      print("File URL:- ----", file.url)  # Apparently this file element does not have url
      print("Sender :-------", sender) # This is the fileloader component
      print("Sender Text: -----", sender.text) # This is the key of the image to which to assign the fileloader loaded image
      print("Key:----", key) # This is the key of the fileloader
      print("Files: ----",  files)
      loaded_image = None
      for element in self.inputs:
        if element.type == "fileLoader" and element.key == key:
          print("Element:----", element)
          print("Element key:---", element.key)
          print("Parameter Key:----",key)
          print("Element type: ----", element.type)
          loaded_image = element.value

          print("Loaded Image:-----", loaded_image)
      if event_name == "change" and file is not None:
          # Get file url to later assign to the image source
          loaded_image_url ='get_file_url', sender.value)
          print("File URL:----", loaded_image_url)
          # Iterate through the form_inputs to find the corresponding Image
          for form_input in self.inputs:
            if form_input.type == "image" and form_input.key == sender.text:
              print("All the following are properties of the image")
              print("Image found")
              print("FormInput:-----", form_input) #This is the image component
              print("Content Type:----",form_input.value.content_type)
              print("Content URL:----",form_input.value.url)
              print("Type: ---", form_input.type) # This is the component type
              print("Value before:-----", form_input.value)
              #print("Source :-----", form_input.value.source)  #Appaarently no such argument source

              # Failed attempts to assign the new image
              ## ------------------------------------------------
              #form_input.source = file  # Assign  the file to the source of the image
              #form_input.value.source = loaded_image_url
              #form_input.source = image_name
              form_input.value.source = image_name

              print("Value after:-----", form_input.value)
              #print("ImageComponent: ------", image_component)

Here is the output of the print statements:

File uploaded in the fileloader_loaded_image event handler:----- <anvil.FileMedia object>
File name:---- Cine.jpg
File URL:---- None

These are properties of the fileloader (in the event handler above)

File:- ---- <anvil.FileMedia object
File URL:- ---- None
Sender :------- <anvil.FileLoader object>
Sender Text: ----- imagen
Key:---- fileloader1
Files: ---- [<anvil.FileMedia object>]
Element:---- FormInput object - key: fileloader1, type: fileLoader, label: <anvil.Label object>, value: None, boundImage:imagen
Element key:— fileloader1
Parameter Key:---- fileloader1
Element type: ---- fileLoader
Loaded Image:----- None
File URL:---- URL not generated

All the following are properties of the image

Image found
FormInput:----- FormInput object - key: imagen, type: image, label: <anvil.Label object>, value: <anvil.LazyMedia object>, boundImage:
Content Type:---- image/jpeg
Content URL:----
Type: — image
Value before:----- <anvil.LazyMedia object>
Value after:----- <anvil.LazyMedia object>

I can’t get to assign the value of the new file to the current image object.
I’ve tried all the variants you can see commented in the code, but they don’t seem to work.
I’m probably missing some conceptual fact that might be the culprit of this code not working.

Here is the app in case you want to check it directly.
Just chose the menu option “Contenido” and when the list of items appears click on any of the descriptions, (the first column), and then go to the fileuploader called “imagen”

I would really appreciate any help in spotting the problem!!
Thank you very much!

Here’s what works without the dynamically created components:

    def file_loader_1_change(self, file, **event_args):
        self.image_1.source = file

Since you say that form_input.source = file did not work, then clearly form_input is not an image component. It may be a wrapper around an image component, but not the component itself. You’ll likely have to drill down farther to get to the actual image component.

Hi @jshaffstall
I feel already like Bruce Willis in Armageddon (countless hours of drilling :grin:)
You saw the code, the image component is created with:

self.input = Image(source=self.image)

and then just passed as parameter.

Is this the correct way of creating the image component in code?
Because I get the <anvil.LazyMedia object> as the contents of whatever is that I’ve created, and then I’m lost in translation :grin:
In the code you probably also saw all the different attemps and approaches I’ve tried. But at the end it was just trial and error, because the theory (as I understand it, which might perfectly be the problem) failed.

Unfortunately, I think this is something I can’t grab because of my limited knowledge of OO, so it quickly becomes a nightmare for me to deal with objects, and this is an object. In this case I hit rock bottom.

My only move left is to just wait for someone to shed a bit of light on me.
Thank you

That’s inside your FormInput component. You’re looping over FormInput components when you are processing the file loader change. So presumably drilling down to the input property will get you your Image component.

So not form_input.source but form_input.input.source


For this general situation, there’s much more you can do beyond just printing the object (which only tells you str(x)): Python objects speak for themselves As one concrete suggestion, when you have an unknown object x, take a look at dir(x).

1 Like

You know, when you say it in such simple words, it seems that there was no other way of thinking about it … and you are right!!! It works.

I wonder why I never saw it that way. And I think I know.
Somewhere in the way, my weak OO mind stopped thinking of FormInput instances as objects, and so I forgot about their properties, except for the ones shown when you write the . after the object name; and in this case as this was happening in the EditContenido Form the dot didn’t show any properties of the FormInput object (you had to knew them or remember that they were there just waiting to be used :exploding_head: )

I bow before wisdom!
Thank you very very much!!!

1 Like

Hi @hugetim
Thank you very much for the suggestion!
I will explore it in this same context, to see if it could have provided me with the “aha” moment I needed to realize what I was missing.

1 Like