Wanjia
Wanjia

Reputation: 817

Dynamically fill mvvm model from indexed array

GetAirports lets me fill _airports if it were to be unindexed this meaning I could also get an airport if I were to use _airport[0]

But getting the airports with this public API link https://desktopapps.ryanair.com/en-gb/res/stations uses an indexed array with objects assigned to them. How can I dynamically fill _airports and extract them without knowing the actual index name?

public async Task<List<Airports>> GetAirports()
{
    string url = _BASEURL;
    if( _airports == null)
        _airports = await GetAsync<List<Airports>>(url);

    return _airports;
}

GetAsync function:

protected async Task<T> GetAsync<T>(string url)
    {
        using (HttpClient client = CreateHttpClient())
        {
            try
            {
                var json = await client.GetStringAsync(url);
                return await Task.Run(() => JsonConvert.DeserializeObject<T>(json));
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return default(T);
            }
        }
    }

Airport model:

public class Airports
{
    public string Name { get; set; }
    public string Country { get; set; }
    public string TimeZone { get; set; }
    public string Latitude { get; set; }
    public string Longitude { get; set; }
}

From the API

"AAL":{
    "name":"Aalborg Airport",
    "country":"DK",
    "timeZone":"DK",
    "latitude":"570535N",
    "longitude":"0095100E"
},
"AAR":{...}

Upvotes: 3

Views: 83

Answers (1)

Nkosi
Nkosi

Reputation: 247323

Here is a work around based on the format of the data returned from the API.

Add an additional property to the model to hold the key/code like AAL

public class Airport { //<-- note the name change of the model
    public string Code { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }
    public string TimeZone { get; set; }
    public string Latitude { get; set; }
    public string Longitude { get; set; }
}

Next refactor the parsing to use Dictionary<string, Airport> and then extract the KeyValuePairs to return the desired type

public async Task<List<Airport>> GetAirportsAsync() { //<-- note the name change
    string url = _BASEURL;
    if( _airports == null) {
        var data = await GetAsync<Dictionary<string, Airport>>(url);
        _airports = data.Select(_ => {
            var code = _.Key;
            var airport = _.Value;
            airport.Code = code;
            return airport;
        }).ToList();
    }

    return _airports;
}

Upvotes: 2

Related Questions