Wierd "duplicated" site on custom domain

What I’m trying to do:
After publishing my application to a custom domain, I am seeing a weird issue where the whole app is “duplicated”, for at lack of a better term.

The app is looking as it should, however the application is “doubled”, meaning by scrolling down, I get another top bar, navigation bar and content page:

Both sites are functional, however I am using the Messaging module from anvil-extras, which seems to only make registrations on the “lower” page. Presumably due to that being the last that is loaded.

Has anyone experienced anything similar?
I hope I am explaining it in a way that makes sense.
If needed, I can provide a clone in a private message.

What I’ve tried and what’s not working:
I am using anvil-extras and HashRouting for my application, as well as using a application structure, which I have used before without issues.

I might be missing something simple, so I hope someone can be of assistance.

Code Sample:

Startup (client)

import anvil.users
import anvil.server
from anvil import open_form

from . import Globals


def startup():
  try:
    Globals.get_initial_data()
    open_form('MainForm')
  except anvil.users.AuthenticationFailed:
    open_form('LoginForm')
  except ValueError as ve:
    pass

if __name__ == '__main__':
  startup()

LoginForm (client)

from ._anvil_designer import LoginFormTemplate
from anvil import *
import anvil.server
from anvil.tables import app_tables
import anvil.users


class LoginForm(LoginFormTemplate):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)


  def login_button_click(self, **event_args):
    """This method is called when the button is clicked"""
    user = anvil.users.login_with_form(allow_remembered=True, allow_cancel=True)
    if user:
      from ..Startup import startup
      startup()

If further code snippets are required, please let me know.

I think you might be running the startup function twice. Once when the startup module loads, because of the last two lines and then again when you call it from the button click handler.

I can see how that is the case, however I am using the exact same structure in another app of mine, without issues.

The structure of the authentication/startup is inspired/copied from a post I read on the forum. I cannot seem to find it at the moment, but looking back my git history of another app, these are the implicated bits:

Startup (client)

import anvil.server
import anvil.server
import anvil.users
from anvil import open_form

from . import Globals


def startup():
  try:
    Globals.get_initial_data()
    open_form('MainForm')
  except anvil.users.AuthenticationFailed:
    open_form('LoginForm')
    

if __name__ == '__main__':
  startup()

Globals (client)

import anvil.server
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
import anvil.server

user = None
data = None


def update_some_global():
  pass


def clear_data():
  global data, user
  data = None
  user = None


def get_initial_data():
  global user, data
  user, data = anvil.server.call('get_initial_data')

LoginForm (client)

from ._anvil_designer import LoginFormTemplate
from anvil import *
import anvil.server
import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables

class LoginForm(LoginFormTemplate):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)

    # Any code you write here will run when the form opens.
    

  def login_button_click(self, **event_args):
    """This method is called when the button is clicked"""
    user = anvil.users.login_with_form(allow_remembered=True, allow_cancel=True)
    if user:
      from ..Startup import startup
      startup()

AuthUtils (server)

import anvil.users
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
import anvil.server


def ensure_user():
  user = anvil.users.get_user()
  if user is None:
    print('user not logged in')
    raise anvil.users.AuthenticationFailed('User not logged in')
  return user


@anvil.server.callable
def get_initial_data():
  print('getting initial data')
  user = ensure_user()
  data = []
  return user, data

As far as I can tell, this is the same way, I do it in my current application. Seems like I’m missing something though…

Apparently, by forcing a refresh wihtout cache (Ctrl + F5), the app reloads and the issue is gone.

If I clear all local storage, cookies etc, the issue returns.

Feel free to send over the clone and link to the live app in a private message.

I suspect it’s something with the MainForm here give that’s the one that seems to be duplicated.

I’ve looked at the app.

There are two calls to login_button_click going on, almost simultaneously.
If you click on the flow_panel in the LoginForm you’ll find that the hide event has been inadvertently set to also run the login_button_click event.

You can check this by printing the event args:

  def login_button_click(self, **event_args):
    print(event_args)
    ...

which logs

{'event_name': 'click', 'sender': <anvil.Link object>}
{'event_name': 'hide', 'sender': <anvil.FlowPanel object>}

I’m marking this as a bug and we’ll look at our implementation of anvil.open_form to prevent this happening in the future.
Removing the hide event will fix the immediate issue

2 Likes

You’re a lifesaver Stu!!!

It would have taken me hours of troubleshooting to figure this one out.

Thank you so much! Both to you for helping with this issue, and to the whole Anvil team, for creating a great product!