Build an Open Data App – Part 2: A Singleton and getting the Data

The next thing to worry about is getting the dataset. We’re also going to implement a design pattern here: a singleton. Why a singleton, you ask? Well, I plan on using this data model throughout the app and don’t want to constantly be downloading the dataset with every new page. Before you implement something like this, it’s a good idea to do some research on the costs and benefits. This solution may work for your idea, or it may not be the best.

To set up the singleton, I start with a private constructor, a property to hold the instance, and a boolean and action.

private static MainDataModel _Instance;
public static MainDataModel Instance
{
    get
    {
        if (_Instance == null)
        {
            _Instance = new MainDataModel();
        }

        return _Instance;
    }
}

public bool IsInitialized = false;
public event Action Initialized;

private MainDataModel() { }

You’ll notice two things immediately: The instance doesn’t have a setter, and the constructor is empty. We don’t need a setter as we’re only creating the instance on the initial call and we’re doing it with a static so it’s always available. As for the empty constructor, this is because we’ll be using asynchronous calls in loading the data and that’s not allowed in constructors. The boolean will allow us to avoid trying to build the instance twice by accident, and the action will be used so we can listen for when the dataset has finished loading.

From here, it’s a matter of getting the data, and we’ll do that with a method, LoadData. Because we’re using asyncs, this method needs to be public and needs to be called from within the app code to allow the dataset to load. Additionally, we’ll need to ensure we have clear purpose with our methods. Be keeping actions separate we’ll better be able to include additional features later, like loading the dataset from local storage rather than always getting it from the web.

public async Task LoadData()
{
    if (!IsInitialized)
    {
        await GetStations();

        if (Initialized != null)
            Initialized();

        IsInitialized = true;
    }
}

private async Task GetStations()
{
    BikeStations = null;
    string jsonString = "";

    jsonString = await GetBikeStationsFromServer(new Uri(BikeStationJsonUrlString, UriKind.Absolute));

    try
    {
        var bikeStationsResponse = JsonConvert.DeserializeObject<bikestationresponse>(jsonString);
        BikeStations = bikeStationsResponse.Stations;
    }
    catch (Exception e)
    {
        int i = 9;
    }
}

private async Task<string> GetBikeStationsFromServer(Uri uri)
{    
    WebResponse retData = null;
    var taskCompletion = new TaskCompletionSource<webresponse>();
            
    try
    {
        if (NetworkInterface.GetIsNetworkAvailable())
        {
            HttpWebRequest request = WebRequest.CreateHttp(uri.OriginalString);

            request.UseDefaultCredentials = true;
            request.ContentType = null;
            request.Accept = JsonContentType;
            request.Method = HttpGetString;

            var ia = request.BeginGetResponse((result) =>
            {
                try
                {
                    taskCompletion.TrySetResult(request.EndGetResponse(result));
                }
                catch
                {
                    taskCompletion.TrySetResult(null);
                }
            }, request);
            
            retData = await taskCompletion.Task;
        }
    }
    catch (Exception ex)
    {
        int i = 9;
    }

    if (retData != null)
    {
        using (var streamResponse = retData.GetResponseStream())
        {
            var sr = new StreamReader(streamResponse);
            return await sr.ReadToEndAsync();
        }
    }
    else
    {
        return "";
    }
}

In the code you’ll see that we’re creating a WebResponse to get the JSON, then a stream reader to convert that response into a string. That string is the JSON, so that’s what we need to parse with Json.NET (line 24). Once it’s been parsed into the appropriate class, we can grab the data we need (the stations) and push it to our property.

Now that we have our JSON downloaded and safely held in our property, we can move on to storing and retrieving that data locally.

This entry was posted in .NET, Building an Open Data App, Open Data, Windows 8, Windows 8.x, Windows Phone. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s