reflex icon indicating copy to clipboard operation
reflex copied to clipboard

When I use pc.redirect, how to handle "redirect same url" error ?

Open heumsi opened this issue 2 years ago β€’ 5 comments

Describe the bug A clear and concise description of what the bug is.

I created a button that redirects the page using pc.redirect .

However, when I click the button twice and redirect to the same url, the following error appears (please refer screenshot).

To Reproduce Steps to reproduce the behavior:

I have commented "here" on the offending part.

class GlobalState(BaseState):
    saved_filters: List[model.SavedFilter] = api.list_saved_filter()
    current_saved_filter: Optional[model.SavedFilter] = model.SavedFilter.default()

    def refresh_saved_filters(self) -> None:
        self.saved_filters = api.list_saved_filter()

    def redirect_saved_filter_content(self, saved_filter_: model.SavedFilter):
        self.current_saved_filter = saved_filter_
        try:
            return pc.redirect("/saved-filters") # here
        except:
            pass


def sidebar():
    return pc.box(
        pc.box(
            pc.link(pc.text("Query", font_size="1em"), href="/query"),
        ),
        pc.box(
            pc.text("Saved filters", font_size="xs", margin="0 0 1rem 0"),
            pc.foreach(
                GlobalState.saved_filters,
                lambda saved_filter: pc.box(
                    pc.link(
                        pc.text(
                            saved_filter.name_,
                            padding="0 0 0 1rem",
                            on_click=lambda: GlobalState.redirect_saved_filter_content(saved_filter.id),  # here
                            font_size="1rem",
                        ),
                        href="/filters",
                    ),
                    padding="0.2rem 0",
                    color="#00000080",
                    _hover={
                        "color": "#000000",
                        "cursor": "pointer",
                    },
                ),
            ),
            padding_top="1rem",
        ),
        width="20%",
        min_width="240px",
        height="100%",
        padding="1rem 1rem 0 0",
        border_right=f"0.07rem solid {style.Color.border}",
    )

Expected behavior A clear and concise description of what you expected to happen.

Error messages should not be displayed even when redirected to the same url.

Screenshots If applicable, add screenshots to help explain your problem.

image

** Specifics (please complete the following information):**

  • Python Version: 3.11.0
  • Pynecone Version: 0.1.13
  • OS: Mac OS Monetrey 12.6
  • Browser (Optional): Chrome 109.0.5414.87 arm 64

Additional context Add any other context about the problem here.

heumsi avatar Jan 23 '23 08:01 heumsi

I see this may be an bug we need to fix, other paths work besides the same path of the page though right?

Alek99 avatar Jan 24 '23 02:01 Alek99

other paths work besides the same path of the page though right?

Right. Okay, I'll wait the time the problem is resolved.

heumsi avatar Jan 24 '23 04:01 heumsi

Hi, I'm new here. Mind if I work on this issue?

Sanyam-Garg avatar Jan 27 '23 06:01 Sanyam-Garg

Sure, thanks! Feel free to take this issue and join the discord if you have any questions or need help

Alek99 avatar Jan 27 '23 06:01 Alek99

Hi. I am unable to reproduce the same error in the following code.

"""Welcome to Pynecone! This file outlines the steps to create a basic app."""
from pcconfig import config

import pynecone as pc

docs_url = "https://pynecone.io/docs/getting-started/introduction"
filename = f"{config.app_name}/{config.app_name}.py"


class State(pc.State):
    """The app state."""
    cnt: int = 0

    def increment(self):
        self.cnt += 1
    
    def decrement(self):
        self.cnt -= 1
    
    def redirect(self):
        return pc.redirect("/")

    pass


def index():
    return pc.hstack(
        pc.button(
            "Decrement",
            color_scheme = "red",
            border_radius = "1em",
            on_click = lambda : State.redirect()
        ),
        pc.heading(State.cnt, font_size = "2em"),
        pc.button(
            "Increment",
            color_scheme = "green",
            border_radius = "1em",
            on_click = State.increment
        ),
    )


# Add state and page to the app.
app = pc.App(state=State)
app.add_page(index, route="/")
app.compile()

I get no error on clicking the decrement button. I get an error if I change the redirected URL to a route that does not exist. (For example, if I change the pc.redirect("/") to pc.redirect("/hello"), then I get the error that @heumsi has mentioned.

Sanyam-Garg avatar Jan 28 '23 12:01 Sanyam-Garg

I think it's some kind of code leak.

danik292 avatar Mar 24 '23 09:03 danik292

I too ran into this issue when I was working with pages. I solved my issue in the following way:

  1. Anything passed into pc.redirect() needs to account for spaces. So these need to be handled.
  2. pc.redirect() should be in lower caps, so using lower() is needed.
  3. Provide the entire route where the redirect needs to go, i.e. the entire path.

Here's an example:


# Endpoint #2: Get specific book by title
def get_book(book_title: str, data: dict):
    def book_page() -> pc.Component:
        # so here when we search for a book title in the input field,
        # our main page to be created is book_page.
        # this will call the book_ui method and display the book we searched for.
        return book_ui(data)

    # this function crates and adds the page so that we can access it.
    # this way, the page is only crated when a title is searched,
    # rather than creating all pages when loading the website/app,
    # some titles have spaces in them, and we should be able to handle this.
    # the below function used replace() to replace the spaces with a hyphen
    route = book_title.replace(" ", "-")

    # moreover, the route should be all lower caps, so we use the .lower() func.
    @pc.route(route=f"/books/{route.lower()}", title=book_title)
    def book_page_route() -> pc.Component:
        return book_page()

    return book_page_route
    # handle the create page for book title search
    def get_book_by_title(self):
        # first, we need to loop through all the data and get the book we searched
        book = [book for book in self.books if book["title"] == self.input_value]
        # get the first element of the list because we are only retunring one book
        book = book[0]
        # call the create book page method and pass in the args
        get_book(self.input_value, book)
        # compile the app
        app.compile()
        # re-route to the corresponding page
        # we repeat the same thing here...
        route = book["title"].replace(" ", "-")
        return pc.redirect(f"http://localhost:3000/books/{route.lower()}")

By doing doing this, I was able to get the correct pages and redirect correctly.

You can also try and printing the pages using app.pages method.

LineIndent avatar Apr 09 '23 15:04 LineIndent

Hi @heumsi , I'm looking at this but same as @Sanyam-Garg , I'm not able to reproduce. It seems to me that the error is complaining more about invalid/non-existing routes? From your error message, seems the problematic lines aren't those with /save-filters, but it's where you have the href="/filters",? Can you point me to a full example if possible? just wanted to make sure that the /filters path is accessible.

jay40233 avatar Apr 23 '23 07:04 jay40233

Agreed - this error means that you are redirecting to a page that does not exist. I created this issue to throw a more clear error message when this happens #1196

picklelo avatar Jun 15 '23 19:06 picklelo