Flet popping a view creates duplicate views?

270 Views Asked by At

On the way to making a basic CRUD application with flet, I noticed that when popping a view, the route change is also triggered which creates a duplicate view on top of the last view. Is this something that can be avoided within the context of the framework, without creating a bunch of checks and try blocks?

Also noticed that when running on a normal web browser, the back button works without this problem. It is only the integrated Flet App back button that has this issue.

I initially tried having the "page.views.clear()" inside the route_change function, however this removes any use for the Flet back button. I guess it would not be a problem if deployed as a web app (you would use the browser back button).

Here is my code (excuse the printf debuggers)

from flet import *



   

def main(page: Page):
    page.title = "Routes Example"
    page.views.clear()
    def route_change(e: RouteChangeEvent):
        print(e.data)

        match e.data:
            case "/":
                page.views.append(
                    View(
                        "/",
                        [AppBar(title=Text("Flet app"),bgcolor=colors.SURFACE_VARIANT),
                        Row(
                            controls=[
                                ElevatedButton("Visit Store",on_click=lambda _:page.go("/store")),
                                ElevatedButton("Visit Inventory",on_click=lambda _:page.go("/inventory")),
                                ElevatedButton("Visit Production",on_click=lambda _:page.go("/production")),
                                    ],
                                )
                        ],
                    )
                )
                print("change from Root route "+str(len(page.views)))
            case "/inventory":
                page.views.append(
                    View(
                        "/inventory",
                        [
                            AppBar(title=Text("Inventory"),bgcolor=colors.SURFACE_VARIANT),
                            ElevatedButton("Go to Production",on_click=lambda _:page.go("/production")),
                            ElevatedButton("Go Home",on_click=lambda _:page.go("/")),
                        ],
                    )
                )
                print("change from Inv route "+str(len(page.views)))
            case "/store":
                page.views.append(
                    View(
                        "/store",
                        [
                            AppBar(title=Text("Store"),bgcolor=colors.SURFACE_VARIANT),
                            ElevatedButton("Go to Production",on_click=lambda _:page.go("/production")),
                            ElevatedButton("Go to Inventory",on_click=lambda _:page.go("/inventory")),
                            ElevatedButton("Go Home",on_click=lambda _:page.go("/")),
                        ],
                    )
                )
                print("change from Store route "+str(len(page.views)))
            case "/production":
                page.views.append(
                    View(
                        "/production",
                        [
                            AppBar(title=Text("Production"),bgcolor=colors.SURFACE_VARIANT),
                            ElevatedButton("Go Home",on_click=lambda _:page.go("/")),
                        ],
                    )
                )
                print("change from Prod route "+str(len(page.views)))
            

        page.update()
    
    def view_pop(e: ViewPopEvent):
        print("Before pop " + page.views[-1].route)
        page.views.pop()
        print("After pop " + page.views[-1].route)            
        top_view = page.views[-1]
        page.go(top_view.route)
        print("After go " + page.views[-1].route)

    page.on_route_change = route_change
    page.on_view_pop = view_pop
    page.go(page.route)


if __name__ == "__main__":
    app(target=main,view=AppView.WEB_BROWSER)

Thank you all!

1

There are 1 best solutions below

1
On BEST ANSWER

I had a similar issue and resolved it by comparing the last route in the view list and the route in the route_change event. The solution is to add the new route in the views list only in case the routes are different. Change:

def route_change(e: RouteChangeEvent):
    print(e.data)

    match e.data:

to

def route_change(e: RouteChangeEvent):
    print(e.data)

    if not page.views or page.views[-1].route != e.data:
        match e.data: