Return value from ViewModel

Heiko 21 Reputation points
2021-05-18T07:51:21.2+00:00

Hello all,

I'm trying to program a login-flow (API with Bearer-Token) and getting the
result back from a ViewModel to the caller.

Here's what i try to achieve:

1) On startup check for username/password in SecureStorage
2) Not found? PushModalAsync a login-page (with a ViewModel behind it)
3) The login-button is bound to a Command (or AsyncCommand in MVVM Helpers)
When the button is clicked, the command shall return a Model-Class
<LoginDataModel> with username and password as string.
4) Login-Page disappears, and the returned <LoginDataModel> is further processed
and sent to the API with httpclient

Everything works - except step 3. How is it done "correctly"?

  • On Disappearing?
  • Can a command return a value/object?
  • Messaging System?

Thank you for your tips and help!
Heiko

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,254 questions
0 comments No comments
{count} votes

Accepted answer
  1. JessieZhang-MSFT 7,706 Reputation points Microsoft Vendor
    2021-05-19T03:08:16.233+00:00

    Hello,

    Welcome to our Microsoft Q&A platform!

    3) The login-button is bound to a Command (or AsyncCommand in MVVM Helpers)
    When the button is clicked, the command shall return a Model-Class
    <LoginDataModel> with username and password as string.
    4) Login-Page disappears, and the returned <LoginDataModel> is further processed
    and sent to the API with httpclient

    When the Login-Page disappears(popup from the stack), the ViewModel behind it will been released .

    But if you want to keep the returned model (LoginDataModel) for later usage, there are several methods to achieve this.

    For example:

    1.define the LoginDataModel as a global class and a prefix for field UserName and field Password as ,for example:

       public  class LoginDataModel  
    {  
        public static string UserName { get; set; }  
        public static string Password { get; set; }  
    
        public LoginDataModel()  
        {  
            UserName = "";  
            Password = "";  
        }  
    }  
    

    2.When the command shall return a Model-Class, then the value of LoginDataModel will been changed.And the value will not lost even if the Login-Page be pop up from the page stack.
    Then you can get the value of LoginDataModel in any other class you want.

        System.Diagnostics.Debug.WriteLine("Name = " + LoginDataModel.UserName +"<----->  pwd = " + LoginDataModel.Password);  
    

    Note:
    Of course, you can also use MessagingCenter to achieve this.
    You need to Publish a message ,Subscribe to a message as follows:

    Publish a message

      string[] values = { name, password};  
      MessagingCenter.Send<ViewModelBase, string[]> (this, "userInfo", values);  
    

    Subscribe to a message

    MessagingCenter.Subscribe<ViewModelBase, string[]> (this, "userInfo", (sender, values) => {  
           DisplayAlert(values[0], values[1], "Ok");  
     });  
    

    Best Regards,

    Jessie Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Heiko 21 Reputation points
    2021-05-19T13:04:30.723+00:00

    Hello Jessie,

    thank you for your helpful answer!

    I thought about your suggestion 2 and realized that my ViewModel still exists, if I pass it as a paramater to my LoginView.
    So for now i did:

    1) put my LoginDataModel in the ViewModel

    public class LoginViewModel
    {
        private LoginDataModel _loginDataModel;
        public LoginDataModel loginDataModel
        {
            get { return _loginDataModel; }
            set { _loginDataModel = value; }
         }
        [...]
    

    2) Bind my entry fields directly to my LoginDataModel

    <Entry Placeholder="E-mail" Text="{Binding loginDataModel.email}" />
    

    3) create all login related things

     LoginViewModel loginViewModel = new LoginViewModel();
     await MainPage.Navigation.PushModalAsync(new LoginPage(loginViewModel));
    

    4) do the login-work in the ViewModel, and close the Page

    OnLoginClicked = new Xamarin.Forms.Command(doLogin);
    
    private async void doLogin(object obj)
    {
        await Application.Current.MainPage.Navigation.PopModalAsync();
    }
    

    After that the login-Data is still accessable in the ViewModel:

    Debug.WriteLine(loginViewModel.loginDataModel.email);
    

    And it works :-)

    Best regards
    Heiko

    0 comments No comments