Home > Mobile >  Best Practice to Load Data from API when navigating to page?
Best Practice to Load Data from API when navigating to page?

Time:04-14

I'm developing a UWP app which gets list of trending anime with its profile picture which is binded to a horizontal ListView. I've made my API call in Page_Loaded event. The problem is, as soon as navigating to that page, the content is loaded but the layout didn't updated the ListView. Am I doing something wrong. If I'm wrong, then what is the correct procedure to call the API request and to Bind the data to ListView?

This is my Data Class:

    public class AnimeObject
    {
        public string Title {get; set;}
        public string coverImage {get; set}
        public int totalEpisodes {get; set}
    }

And, this is my Page_Loaded Event:

    private async void Page_Loaded(object sender, RoutedEventArgs e)
    {
        ListView.ItemsSource = await apiHandler.RequestAPI();
    }

Here, the RequestAPI Function is returning List<AnimeObject> and the ListView is simply a datatemplate, which is least to worry.

Edit:

As Nico Zhu asked, I've provided a sample code. This code contains api which is a graphql API.

MainPage.xaml:

<Grid>
    <TextBlock Text="{x:Bind animeDetails.data.Page.media[0].title}"/>
    <TextBlock Text="{x:Bind animeDetails.data.Page.media[0].id}"/>
    <Image Source="{x:Bind animeDetails.data.Page.media[0].coverImage}"/>
</Grid>

MainPage.xaml.cs:

namespace TestAppForNotify
{
    public sealed partial class MainPage : Page
    {
        public dataClass.AnimeObject animeDetails;
        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void Page_Loaded(object sender, RoutedEventArgs e)
        {
            animeDetails = JsonConvert.DeserializeObject<dataClass.AnimeObject>(
                await requestAPI()
            );
        }

        private async Task<string> requestAPI()
        {
            string query = @"
            query{
              Page(perPage: 20, page: 1){
                media(sort: TRENDING_DESC){
                  id
                  title{
                    english
                  }
                  coverImage {
                    extraLarge
                  }
                }
              }
            }";

            var client = new HttpClient();

            var jsonString = new StringContent(
                JsonConvert.SerializeObject(
                    new
                    {
                        query = query
                    }
                ),
                System.Text.Encoding.UTF8,
                "application/json"
            );

            var request = await client
                .PostAsync("https://graphql.anilist.co", jsonString);

            var response = await request
                .Content
                .ReadAsStringAsync();

            Debug.WriteLine(response);

            return response;
        }
    }
}

I've used Newtonsoft.Json for json Serializing..

Please Help me...

CodePudding user response:

It looks you bind wrong property, please edit your binding like the following.

<ListView x:Name=" " Margin="0,50,0,0">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Background="White">
                <TextBlock Text="{Binding title.english, Mode=OneWay}" />
                <TextBlock Text="{Binding id, Mode=OneWay}" />
                <Image Source="{Binding coverImage.extraLarge, Mode=OneWay}" Visibility="Visible" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Code Behind

private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
   
     animeDetails = JsonConvert.DeserializeObject<Model.AnimeObject>(
           await requestAPI()
       );
    AnimeList.ItemsSource = animeDetails.data.Page.media;
}

Update

private Model.AnimeObject _animeDetails;
public Model.AnimeObject animeDetails
{
    get { return _animeDetails; }
    set
    {
        _animeDetails = value;
        OnPropertyChanged();
    }
}

Xaml Code

<StackPanel
    Width="300"
    Height="300"
    Background="White">
    <TextBlock Text="{x:Bind animeDetails.data.Page.media[1].title.english, Mode=TwoWay}" />
    <TextBlock Text="{x:Bind animeDetails.data.Page.media[1].id, Mode=TwoWay}" />
    <Image Source="{x:Bind animeDetails.data.Page.media[1].coverImage.extraLarge, Mode=TwoWay}" />
</StackPanel>
  • Related