uno.extensions icon indicating copy to clipboard operation
uno.extensions copied to clipboard

navigator.GetDataAsync fails when navigating within lower levels. Only works for (Wasm/Android/iOS)

Open hbraasch opened this issue 1 year ago • 1 comments

Current behavior

When using Uno.Toolkit.UI Navigation, I've come across an issue where on the return from await navigator.GetDataAsync , it only works as expected under WASM/Android/iOS, not for UWP/WinUI?

On all frameworks, when executing the following command from a toplevel MainPage, navigating to another page (level2), passing data and expect returned data using the following instructions, it works fine:

var result = await navigator.GetDataAsync<ResponseData>(this, data: new CommandData { Message = "Data from MainPage" });
Name = result.Message;

The component bound to the Name value updates nicely on the page.

However, for UWP/WinUI, when I navigate to the second page (level2), then navigate to another page (level3), again using the same command :

var result = await navigator.GetDataAsync<ResponseData>(this, data: new CommandData { Message = "Data from SecondPage" });
Name = result.Message;

It returns fine from the third page BUT... Another instance of the second page's viewmodel gets instantiated (i.e. the constructor runs) directly after the GetDataAsync returns. AND whatever UI activities resume thereafter, does not update e.g. the Name = result.Message is not updating the UI. I think it's because the datacontext viewmodel has changed.

So, the question is. Why does GetDataAsync work when navigating away from the first level, but fails when navigating from within lower levels (SecondPage to ThirdPage)

I've provided a simple example project solution that demonstrates the issue

It's here: https://github.com/hbraasch/UnoNavigatorTester.git

Expected behavior

When GetDataAsync returns, the viewmodel must not be re-instantiated, and any UI activities after the return in the same method must be effective

As I mentioned, it works fine under WASM/Android/iOS?

How to reproduce it (as minimally and precisely as possible)

Install the solution: https://github.com/hbraasch/UnoNavigatorTester.git

Run until you reach this page:

image

Not the textbox displays [Value set by MainPage]. We want to modify this on return from the next level navigation; Press the [Go directly to third page] button. See this display:

image

This is the page that supplies data for return to the calling page. Press the [Go back] button. You are now back to MainPage and see the value updated to [DataFromThirdPage]

image

This demonstrates correct operation when navigating from root level

Now press the [Go to second page] button. See this display:

image

Not the textbox displays [Value set by SecondPage]. We want to modify this on return from the next level navigation; Press the [Go to third page] button. See this display:

image

This is the page that supplies data for return to the calling page. Press the [Go back] button. See what displays next:

image

Notice the textbox still displays [Value set by SecondPage]. No update.

The exact same WASM result:

image

If you set breakpoints inside the SecondPageViewModel, you will notice its constructor fired unexpectedly.

Workaround

I've discover that during the re-instantiation of the viewmodel, the correct ResponseData object is returned through injection. By adding this to the constructor, one can retrieve and update UI elements.

public SecondViewModel(INavigator navigator, string command, ResponseData response)

However, to make use of this makes for for ugly coding, especially if the viewmodel gets data from other routes too, and these data will be null when this constructor gets called at that instance. It completely defeats the purpose of await/async.

I was hoping the viewmodel will not be instantiated when GetDataAsync returns, so one can carry on thereafter and simply update the "need to change" UI elements.

Works on UWP/WinUI

Works perfectly under WASM/Android/iOS

image

iOS image

Not for UWP/WinUI

Environment

Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia, Other

NuGet package version(s)

N/A

Affected platforms

Windows (WinAppSDK), Desktop

IDE

Visual Studio 2022

IDE version

N/A

Relevant plugins

N/A

Anything else we need to know?

N/A

hbraasch avatar Dec 06 '24 05:12 hbraasch