Mvvmcross: awaiting MvxViewModel.Initialize() is buggy

Created on 21 Nov 2018  路  8Comments  路  Source: MvvmCross/MvvmCross

馃悰 Bug Report

So the docs say that all heavy loading should be done in MvxViewModel.Initialize(), however anytime I put an await inside that method, the app doesnt load the VM's view. I originally had all my code from ViewCreated() inside Initialize().

namespace RDPReader.Core.ViewModels
{
    public class AppConfigViewModel : BaseViewModel
    {
        readonly IMvxNavigationService _navigationService;

        public AppConfigViewModel(IMvxNavigationService navigationService)
        {
            _navigationService = navigationService;

            ShowMainViewModelCommand = new MvxAsyncCommand(async () => await _navigationService.Navigate<MainViewModel>());
            ShowLoginViewModelCommand = new MvxAsyncCommand(async () => await _navigationService.Navigate<LoginViewModel>());
        }

        // MvvmCross Lifecycle
        public override async Task Initialize()
        {
            //await Task.Delay(4000);

            //return base.Initialize();
        }

        public override async void ViewCreated()
        {
            base.ViewCreated();

            await Task.Delay(1000);

            LoadingMessage = "Carregando X";

            await Task.Delay(1000);

            LoadingMessage = "Carregando Y";

            await Task.Delay(1000);


            await _navigationService.Navigate<MainViewModel>();
        }

        // MVVM Properties
        string _loadingMessage;
        public string LoadingMessage
        {
            get => _loadingMessage;
            set => SetProperty(ref _loadingMessage, value);
        }

        // MVVM Commands
        public IMvxAsyncCommand ShowMainViewModelCommand { get; }
        public IMvxAsyncCommand ShowLoginViewModelCommand { get; }

        // Private Methods
    }
}

Expected behavior

I wanted to load some things and present to the user what is being loaded onscreen through LoadingMessage property, after completion navigate to next screen.

Reproduction steps

Remove the commented await Task.Delay inside Initialize and it will stop working (it will stay stuck on SplashScreen), comment it again and it works. The question is why is it like that? For now I'm doing all the loading on ViewCreated(). So either there is a bug or the docs need to be updated.

Configuration

Version: 6.2.2

Platform:

  • [x] :iphone: iOS
  • [x] :robot: Android
  • [ ] :checkered_flag: WPF
  • [x] :earth_americas: UWP
  • [ ] :apple: MacOS
  • [ ] :tv: tvOS
  • [x] :monkey: Xamarin.Forms
needs-investigation up-for-grabs

Most helpful comment

the same issue for me...
as for temporary solution I've moved my initialization to ViewAppeared method

All 8 comments

I can confirm this bug in the playground project.
In the RootViewModel.cs, just uncomment this line in Initialize() and the bug can be reproduced.

// await Task.Delay(5000);

I can confirm this bug too, when I call async method in Initialize() which has await Task.Delay(150) it stuck my app on LaunchScreen in iOS project.

I think this is what I'm seeing in #3221

Happens for me too. I currently fixed this by removing the await in MvxAppStart.NavigateToFirstViewModel>:

        protected override async Task NavigateToFirstViewModel(object hint = null)
        {
            try
            {
                //await NavigationService.Navigate<TViewModel>();
                NavigationService.Navigate<TViewModel>();
            }
            catch (System.Exception exception)
            {
                throw exception.MvxWrap("Problem navigating to ViewModel {0}", typeof(TViewModel).Name);
            }
        }

@Gabriel1786
I came across similar issue few days ago and my solution was to just call another async method from inside Initialize()

public override Task Initialize()
        {
            return DoSomeAsyncStuffAsync();
        }

        public async Task DoSomeAsyncStuffAsync()
        {
            var result = await _customService.GetResultAsync();
            var something = await _anotherCustomService.GetSomethingElseAsync(result);
            DoSomethingElseAsync(something);
        }

Hi guys, any update on this one?
Still having this issue on iOS platform.
I've moved stuff to Start() method and it helps, but still looks weird.

the same issue for me...
as for temporary solution I've moved my initialization to ViewAppeared method

me too. I do as sprzygoda.

Was this page helpful?
0 / 5 - 0 ratings