0

I have created a class, in Xamarin Forms, that requests to a web API about the details of countries. Right now, I am testing only with a country.

However, once the line "HttpResponseMessage response = await client.GetAsync(uri);" is executed, the app does nothing additional.

In order to validate if the app executes other instructions after this line, I have included additional lines to write the sequence into the device log.

All the lines before the previous instruction are written into the log and none of them after this instruction.

On the other hand, the screen of the device remains blank, without insert the Label created by code.

Here is the code of the class and the method that consumes the API.

...

using Android.Util;
using System.Net.Http;
using System.Threading.Tasks;

class Country
{
    public int iIdCountry { get; set; }
    public string sCountryName { get; set; }
    public string sCountryIsoCode { get; set; }
    public string sCountryPhoneCode { get; set; }
    public bool bCountryContainsPrefix { get; set; }
    public bool bCountryActive { get; set; }

    private static readonly HttpClient client = new HttpClient();

    public static async Task<Country> GetCountryAsync(int id)
    {
        string baseUri = new BaseUri().baseUri;
        string sufixUri = "/CountriesApi/GetItem/" + id;
        var uri = baseUri + sufixUri;
        string tag = "myapp";
        Country country = null;

        HttpResponseMessage response = await client.GetAsync(uri);
        Log.Info(tag, "Response received");

        if (response.IsSuccessStatusCode)
        {
            country = await response.Content.ReadAsAsync<Country>();
            Log.Info(tag, "Country received");
        }

        Log.Info(tag, "Country returned");
        return country;
    }
}

...

This is the component that makes the call to the previous class:

...

using Android.Util;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace EnubexMobile.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]

    public partial class Start : ContentPage
    {
        public Start()
        {
            var stackLayout = new StackLayout();
            string tag = "myapp";

            InitializeComponent();
            Log.Info(tag, "Started");

            var country = Country.GetCountryAsync(1).GetAwaiter().GetResult();
            Log.Info(tag, country.sCountryName);

            var label = new Label() { Text = country.sCountryName };
            Log.Info(tag, "Label created");

            stackLayout.Children.Add(label);
            Log.Info(tag, "Label added");
        }

        private void InitializeComponent()
        {
            throw new NotImplementedException();
        }
    }
}

...

The idea is to insert a label into the StackLayout with the name of the country received from the API.

Could someone help me to understand what I am missing here?

Thanks !

Regards,

Henry
  • 167
  • 1
  • 1
  • 8
  • 2
    don't call async methods from the constructor – Jason Aug 06 '21 at 02:56
  • Calling async method is not good habit from the constructor still if you want to use you can write like this new Action(async () => { await Country.GetCountryAsync(1);}).Invoke(); – Adit Kothari Aug 06 '21 at 11:03
  • Note that the limitation of code @AditKothari shows, is that it is "fire and forget". Can be used to start an async task that will be run independently, *if* you don't need any return value from that task. So it can't be used for the code shown in question, where the return value is needed before the rest of the code runs. – ToolmakerSteve Aug 06 '21 at 12:56
  • One approach: Add parameter `country` to constructor: `public Start(MyCountryType country) {...}`. Have the caller do GetCountryAsync first, so can do `new Start(country)`. To keep that logic in Start class, add a static method: `public async static Start Create() { var country = await Country...; return new Start(country); }` Usage: `await Start.Create()`. This puts the web query into an async context, instead of the constructor. – ToolmakerSteve Aug 06 '21 at 13:08

0 Answers0