navigator.GetDataAsync fails when navigating within lower levels. Only works for (Wasm/Android/iOS) #2635
Labels
kind/bug
Something isn't working
triage/untriaged
Indicates an issue requires triaging or verification.
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:
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 :
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 effectiveAs 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:
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:
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]
This demonstrates correct operation when navigating from root level
Now press the [Go to second page] button. See this display:
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:
This is the page that supplies data for return to the calling page. Press the [Go back] button.
See what displays next:
Notice the textbox still displays [Value set by SecondPage]. No update.
The exact same WASM result:
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
iOS
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
The text was updated successfully, but these errors were encountered: