MVVM Binding Data not working

HistoryaHistorya USMember ✭✭✭
edited April 2017 in Xamarin.Forms

hello,
i am facing problem with displaying the data in the view, the data not showing i can't find where is the problem, so this is my code :

the view.xaml:

         <ContentPage.BindingContext>
                        <vm:MenuViewModel/>
                    </ContentPage.BindingContext>
        <StackLayout>
         <Grid Padding="10,1,10,0">
                                <Label Text="{Binding SelectedUser.firstName}" TextColor="White" FontSize="19" HorizontalOptions="Center" />
                                <Label Text="{Binding SelectedUser.job}" TextColor="White" FontSize="9" Margin="2,23,20,0" HorizontalOptions="Center"/>
                                </Grid>
        </StackLayout>

the view.cs:

  public TimelineMenuPage(string userid,string token)
        {
            InitializeComponent();
            NavigationPage.SetHasNavigationBar(this, false);
            this.userid = userid;
            this.usertoken = token;           
            OnAppearing();
        }
 protected override void OnAppearing()
        {
            base.OnAppearing();
            MenuViewModel vm = new MenuViewModel();
           vm.GetAsyncUsers(userid,usertoken);

        }

the viewmodel:

        public AuthUser.User SelectedUser
        {
             get  => _selectedUser; 
            set
            {
                _selectedUser = value; 
                OnPropertyChanged();
            }
        }
  public async Task<AuthUser.User> GetAsyncUsers(string id,string token)
        {
            var serv = new Services.AuthServ();

            SelectedUser = await serv.GetUser(id,token);
            return SelectedUser;
        }

the service:
public async Task<AuthUser.User> GetUser(string userid,string token)
{
RestGetUser<AuthUser.User> restclient = new RestGetUser<AuthUser.User>();
AuthUser.User user= await restclient.GetAsyncUser(userid,token);
return user;

        }

the restcall:
public async Task<AuthUser.User> GetAsyncUser(string userid, string token)
{
using (var client = new RestSharp.Portable.HttpClient.RestClient(uri))
{
var request = new RestRequest(Method.GET);

                    request.AddHeader("Content-Type", "application/json; charset=utf-8");
                    request.AddHeader("Cookie", "JSESSIONID="+token);
                    IRestResponse response = await client.Execute(request);
                  //  response.Cookies.GetEnumerator();
                    var responseData = JsonConvert.DeserializeObject<AuthUser.RootObject>(response.Content);
                   AuthUser.User userData = responseData.results.user;
                    return userData;
                }

and this should the retrieved data:

Best Answer

  • HistoryaHistorya US ✭✭✭
    Accepted Answer

    @AlessandroCaliaro it worked with changing the Binding from XAML to cs, so the XAML didn't work , and in the cs it did :

    BindingContext = new MenuViewModel(userid,token);

    thank you for your help,
    thank you @NMackay too

Answers

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @RefkaBenmahmoud said:
    hello,
    i am facing problem with displaying the data in the view, the data not showing i can't find where is the problem, so this is my code :

    the view.xaml:
    <ContentPage.BindingContext>

    </ContentPage.BindingContext>
    <StackLayout....

    the view.cs:

      public TimelineMenuPage(string userid,string token)
            {
                InitializeComponent();
                NavigationPage.SetHasNavigationBar(this, false);
                this.userid = userid;
                this.usertoken = token;           
                OnAppearing();
            }
     protected override void OnAppearing()
            {
                base.OnAppearing();
                MenuViewModel vm = new MenuViewModel();
               vm.GetAsyncUsers(userid,usertoken);
    
            }
    

    the viewmodel:

            public AuthUser.User SelectedUser
            {
                 get  => _selectedUser; 
                set
                {
                    _selectedUser = value; 
                    OnPropertyChanged();
                }
            }
      public async Task<AuthUser.User> GetAsyncUsers(string id,string token)
            {
                var serv = new Services.AuthServ();
    
                SelectedUser = await serv.GetUser(id,token);
                return SelectedUser;
            }
    

    the service:
    public async Task<AuthUser.User> GetUser(string userid,string token)
    {
    RestGetUser<AuthUser.User> restclient = new RestGetUser<AuthUser.User>();
    AuthUser.User user= await restclient.GetAsyncUser(userid,token);
    return user;

    }
    the restcall:
    public async Task<AuthUser.User> GetAsyncUser(string userid, string token)
    {
    using (var client = new RestSharp.Portable.HttpClient.RestClient(uri))
    {
    var request = new RestRequest(Method.GET);

    request.AddHeader("Content-Type", "application/json; charset=utf-8");
    request.AddHeader("Cookie", "JSESSIONID="+token);
    IRestResponse response = await client.Execute(request);
    // response.Cookies.GetEnumerator();
    var responseData = JsonConvert.DeserializeObject<AuthUser.RootObject>(response.Content);
    AuthUser.User userData = responseData.results.user;
    return userData;
    }

    and this should the retrieved data:

    How is _selectedUser defined?

    If you use a "async" method you should "await" it...

  • HistoryaHistorya USMember ✭✭✭

    @AlessandroCaliaro like this : private AuthUser.User _selectedUser;

  • HistoryaHistorya USMember ✭✭✭

    @AlessandroCaliaro it is already awaited

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    GetAsyncUsers is not awaited when you call it.

    Do you have any warnings in Application output dialog box?

  • HistoryaHistorya USMember ✭✭✭

    @AlessandroCaliaro yes , i get this :

    Warning CS4014 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

    here in the view.cs :

    protected override void OnAppearing()
            {
                base.OnAppearing();
                MenuViewModel vm = new MenuViewModel();
               **vm.GetAsyncUsers(userid,usertoken);**
    
            }
    

    i awaited it with async but still same in the call of on appearing in the ctor:

     public  TimelineMenuPage()
            {
                InitializeComponent();
                NavigationPage.SetHasNavigationBar(this, false);
             **    OnAppearingAsync();**
            }
    
            protected async Task OnAppearingAsync()
            {
                base.OnAppearing();
                MenuViewModel vm = new MenuViewModel();
                await vm.GetAsyncUsers(userid, usertoken);
    
            }
    
  • NMackayNMackay GBInsider, University mod

    2nd approach will not be awaited.

    try

    protected override async void OnAppearing()
            {
                base.OnAppearing();
                MenuViewModel vm = new MenuViewModel(); // I'd init this in the page constructor
               await vm.GetAsyncUsers(userid,usertoken);**
    
            }
    

    I'd maybe suggest checking out Prism or another MVVM framework to abstract away this stuff to make your life easier.

  • HistoryaHistorya USMember ✭✭✭

    @NMackay
    what should i do with it in the ctor? i can't make it await

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Yes, you have only moved the problem in the constructor...

    You have not to create another method, just override OnAppearing and add async and await, as @NMackay say

    protected override async void OnAppearing()
        {
            base.OnAppearing();
            MenuViewModel vm = new MenuViewModel();
           await vm.GetAsyncUsers(userid,usertoken);
    
        }
    
  • HistoryaHistorya USMember ✭✭✭

    @AlessandroCaliaro @NMackay
    it doesn't accept the async with override, that's why i removed the override from the onappearing method

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    remove Task, add void

  • HistoryaHistorya USMember ✭✭✭
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭
    edited April 2017

    @RefkaBenmahmoud we are loosing our time...

    protected override async void OnAppearing()
        {
            base.OnAppearing();
            MenuViewModel vm = new MenuViewModel();
           await vm.GetAsyncUsers(userid,usertoken);
    
        }
    

    put this code in your prj and Build... it is the third time me an @NMackay try to help you

  • HistoryaHistorya USMember ✭✭✭

    thank you @AlessandroCaliaro this has accepted the async without any warning or error, but still not showing the data in the view

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    any other message in Application Output tab?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Does your Model implement INPC?

  • HistoryaHistorya USMember ✭✭✭

    @AlessandroCaliaro yes it does

  • HistoryaHistorya USMember ✭✭✭
    Accepted Answer

    @AlessandroCaliaro it worked with changing the Binding from XAML to cs, so the XAML didn't work , and in the cs it did :

    BindingContext = new MenuViewModel(userid,token);

    thank you for your help,
    thank you @NMackay too

Sign In or Register to comment.