PDF generation fails for RepeatingPanels

Yes I know this is the wrong topic, I can’t post to bug reports.

(fairly) minimal repro:
https://anvil.works/build#clone:3WFJOKH5HBXDNYK4=GNU4L4CC7BTUIXIX3EQSOTJK

Output of said repro:

When attempting to generate a PDF of a form containing a RepeatingPanel that uses its item, Anvil says that there is ‘no such form’ - and the PDF renders as expected when the items attribute of the RepeatingPanel is not set. There isn’t any obvious bug in my code so - can anyone tell me what’s going on?

Welcome to the forum!

Before trying to render to PDF you should try to render to the browser. If it doesn’t work on the browser it will not work to PDF.

If you add a button that shows the form, for example with this:

def button_2_click(self, **event_args):
  open_form('Form1.Form2', 
          "Test header",
          [
              ["Row 1", "row 1 field 1", 'item 1', 'item 2'],
              ["Row 2", "row 2 field 1", 'item 1', 'item 2', 'item 3'],
              ["Row 3", "row 3 field 1", 'item 1', 'item 2'],
              ["Row 4", "row 4 field 1", 'item 1'],
          ])

you will see that the form doesn’t work on the browser either.

And while you try that, you will see an error message on the left panel of the IDE saying SyntaxError: Tuple unpacking with stars is not supported. This is one of the limitations of Skulpt, the javascript based Python interpreter. There are a few limitations, but they usually have easy workarounds.

The following changes allow the form to show on the browser and to render as PDF:

def button_2_click(self, **event_args):
  open_form('Form1.Form2', 
          "Test header",
          [
              ["Row 1", "row 1 field 1", ['item 1', 'item 2']],  # use a list here to avoid unpacking on the client side
              ["Row 2", "row 2 field 1", ['item 1', 'item 2', 'item 3']],
              ["Row 3", "row 3 field 1", ['item 1', 'item 2']],
              ["Row 4", "row 4 field 1", ['item 1']],
          ])

user, total, months = self.item  # the 3rd item is already a list, no need to unpack
self.label_1.text = user
self.label_2.text = total
for month in months:
  Label(text=month, align='right')  # right must be in quotes
4 Likes

Ah thank you! Will implement this now. Is there a way to embed the form within another form? (specifically from a server module, which is the use case I have currently)

Also: completely missed that I forgot the quotes; the error is still a little confusing, however, and could probably be handled better for the user

I must be misunderstanding what this line does:

because I assumed that that would add a label to the right of my row - but it doesn’t. Do you know how to fix that?

I tried to reclone the app, but now it has changed and I don’t see that line. I don’t remember how it was before, but looking at the snippets of code in this post I would say that line does nothing.

You could do something like self.container.add_component(Label(text=month)) to create a label and add it to a container, but the loop in my snippet seems to create one label per month and do nothing with them.

You can embed a form within another form of the same app by dragging it from the left pane of the IDE into the designer of the second form, or you can use self.container.add_component(Form2()) to add it to a container inside any form.
You can also create a form in an app, define it as custom component and reuse it inside other apps.

Have a look at this for an overview of what’s possible.

What error is still confusing?

‘No such form’ when the actual error is a skulpt error - should be more like ‘Form raised error: [error]’

Also: Resolved my issue with that line, documentation is a little confusing when introducing programmatic component addition; it shows the demo of adding a label but doesn’t mention the necessity of add_component until a paragraph or so below

When something goes wrong while rendering a form, the form is not going to say what went wrong. I would say you were lucky the form told you No such form, it usually shows a white page :slight_smile: .

The right way to get good diagnostics is to show the form and look at the errors on the on the left pane of the IDE. They are usually very clear, and have links to the lines with the error. You can also access errors of past sessions and sessions running outside of the IDE inside the app log by clicking on the gear in the IDE.

You had bad luck because you started by trying to render a form to PDF without testing whether the form was working.