3

This is our expected output.
enter image description here

And this is the current output.
enter image description here

And this is the source code for the current output.

import pynecone as pc

def show_items(item):
    return pc.box(
        pc.text(item),
        bg="lightgreen"
    )


class ExampleState(pc.State):
    my_objects = [["item1", "desc1"], ["item2", "desc2"]]
    print(my_objects)


def home():
    homeContainer = pc.container(
        pc.hstack(
            pc.container(
                # watch list
                pc.vstack(
                    pc.container(h="20px"),
                    pc.hstack(
                        pc.heading("Example List", size="md"),
                    ),
                    pc.grid(
                        pc.foreach(ExampleState.my_objects, show_items),
                        template_columns="repeat(5, 1fr)",
                        h="20vh",
                        width="100%",
                        gap=4,
                    ),
                    justifyContent="start",
                    align_items="start",
                ),
                height="100vh",
                maxWidth="auto",
            ),

            bg="#e8e5dc",
        ),
    )

    return homeContainer


app = pc.App(state=ExampleState)
app.add_page(home, route="/")
app.compile()

In this example, we cannot make our expected output. In the above example, if we change the code from

pc.text(item)

to

pc.text(item[0])

, then we will get the following error message

  File "xxxx_some_code.py", line 47, in <module>
    app.add_page(home, route="/")
  File "/xxxx/opt/anaconda3/envs/pynecone-121-py311/lib/python3.11/site-packages/pynecone/app.py", line 261, in add_page
    raise e
  File "/xxxx/opt/anaconda3/envs/pynecone-121-py311/lib/python3.11/site-packages/pynecone/app.py", line 252, in add_page
    component = component if isinstance(component, Component) else component()
                                                                   ^^^^^^^^^^^
  File "xxxx_some_code.py", line 26, in home
    pc.foreach(ExampleState.my_objects, show_items),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/xxxx/opt/anaconda3/envs/pynecone-121-py311/lib/python3.11/site-packages/pynecone/components/layout/foreach.py", line 48, in create
    children=[IterTag.render_component(render_fn, arg=arg)],
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/xxxx/opt/anaconda3/envs/pynecone-121-py311/lib/python3.11/site-packages/pynecone/components/tags/iter_tag.py", line 71, in render_component
    component = render_fn(arg)
                ^^^^^^^^^^^^^^
  File "xxxx_some_code.py", line 5, in show_items
    pc.text(item[0]),
            ~~~~^^^
  File "/xxxx/opt/anaconda3/envs/pynecone-121-py311/lib/python3.11/site-packages/pynecone/var.py", line 181, in __getitem__
    raise TypeError(
TypeError: Could not index into var of type Any. (If you are trying to index into a state var, add a type annotation to the var.)

We also read the document related to pc.grid and pc.foreach.

And still have no idea how to fix this issue from the two documents.

So, what can we do if we want to get detailed information from the item and show it on the layout?

1 Answer 1

2

The key point is that the pc.foreach cannot use something like list[list] or list[dict].
The following code can answer our question.
It run well and fit the expected output. After testing,
It runs well on pynecone==0.1.20 and pynecone==0.1.21

import pynecone as pc
class MyObject(pc.Model, table=True):
    title:str 
    desc:str
    def __init__(self, title, desc):
        self.title = title
        self.desc = desc
    def __repr__(self) -> str:
        return "("+self.title+","+self.desc+")"
 
def show_object(object:MyObject):
    return pc.box(
        pc.vstack(
            pc.hstack(
                pc.text(
                    "title:",
                    font_size="1em",
                ),
                pc.text(
                    object.title,
                    font_size="1em",
                ),
            ),
            pc.hstack(
                pc.text(
                    "desc:",
                    font_size="1em",
                ),
                pc.text(
                    object.desc,
                    font_size="1em",
                ),
            ),
        ),
        bg="lightgreen"
    )


class ExampleState(pc.State):
    # my_objects = [{"item":"item1", "desc":"desc1"}, {"item":"item2", "desc":"desc2"}]
    """
    my_objects:list[MyObject] = [
        MyObject("title1", "desc1"),
        MyObject("title2", "desc2"),
    ]
    """
    # generate objects by loop 
    my_objects:list[MyObject] = [ MyObject("title"+str(i), "desc"+str(i)) for i in range(37)]
    


def home():
    homeContainer = pc.container(
        pc.hstack(
            pc.container(
                # watch list
                pc.vstack(
                    pc.container(h="20px"),
                    pc.hstack(
                        pc.heading("Example List", size="md"),
                    ),
                    pc.grid(
                        #pc.foreach(ExampleState.my_objects, show_items),
                        pc.foreach(ExampleState.my_objects, show_object),
                        template_columns="repeat(5, 1fr)",
                        h="20vh",
                        width="100%",
                        gap=4,
                    ),
                    justifyContent="start",
                    align_items="start",
                ),
                height="100vh",
                maxWidth="auto",
            ),

            bg="#e8e5dc",
        ),
    )
    return homeContainer

app = pc.App(state=ExampleState)
app.add_page(home, route="/")
app.compile()

The following is our expected output.
enter image description here

The solution is we need to create a class.

class MyObject(pc.Model, table=True):
    title:str 
    desc:str
    def __init__(self, title, desc):
        self.title = title
        self.desc = desc
    def __repr__(self) -> str:
        return "("+self.title+","+self.desc+")"

And we show the layout by show_object

def show_object(object:MyObject):

In the show_object function, we get detailed information
about the item by getting the member from the object.

Not the answer you're looking for? Browse other questions tagged or ask your own question.