0

I am trying to fetch Customer data to parse them into customer object to display on TableView. The following code sometimes works, sometimes not. Whenever it does crash, it shows Customer data is empty in the foreach loop even though I run the same code every time. I do not have clue what could be wrong in this circumstances. I am quite new on this platform. If I am missing anything/ extra information, please let me know.

namespace TableViewExample
{   
    public partial class MyDataServices : ContentPage
    {   
        private ODataClient mODataClient;
        private IEnumerable <IDictionary<string,object>> Customers;

        public MyDataServices ()
        {
            InitializeComponent ();
            InitializeDataService ();
            GetDataFromOdataService ();

            TableView tableView = new TableView{ };
            var section = new TableSection ("Customer");

            foreach (var customers in Customers) {
                //System.Diagnostics.Debug.WriteLine ((string)customers ["ContactName"]);
                var name = (string)customers ["ContactName"];
                var cell = new TextCell{ Text = name };
                section.Add (cell);
            }
            tableView.Root.Add (section);

            Padding = new Thickness (10, 20, 10, 10);
            Content = new StackLayout () {
                Children = { tableView }

            };


        }


        private void InitializeDataService(){

            try {
                mODataClient = new ODataClient ("myURL is here");

            }

            catch {
                System.Diagnostics.Debug.WriteLine("ERROR!");

            }
        }

        private void GetDataFromOdataService (){

            try {
                Customers = mODataClient.For ("Customers").FindEntries ();
            }

            catch {
                System.Diagnostics.Debug.WriteLine("ERROR!");

            }

        }
    }
}
Stephane Delcroix
  • 16,134
  • 5
  • 57
  • 85
casillas
  • 16,351
  • 19
  • 115
  • 215
  • 1
    Where does it crash? What's the exception you get? What are you running it on? Are you crashing a simulator? Or on a device? Which simulator? Which device? – Matt Burland Oct 09 '14 at 14:20
  • it crashes on simulator, I have not tested on device yet. I am only testing with iPhone 5 with iOS 8.0 in simulator – casillas Oct 09 '14 at 14:24
  • It was showing that Customer is empty. I tried to get that error, but out of luck it did not come up even though I have run the app almost 30 times. – casillas Oct 09 '14 at 14:30
  • If `Customers` is empty, I don't see why it would crash (`foreach` would be skipped and you add an empty `section`). Does it *actually crash*? With an exception? Or does it just not do what you expect? – Matt Burland Oct 09 '14 at 14:37
  • I wish I could get a snapshot of the crash. But I could not able to get after I post this question. I have came across that I should use async. for webservice method. Am I right? – casillas Oct 09 '14 at 14:46
  • such as public async void InitializeDataService() ? then in order to match async, then put await in the try and catch condition, in the catch I should create an alert with await DisplayAlert ("......"); – casillas Oct 09 '14 at 14:46

1 Answers1

1

Its hard helping out here, however here are some things to consider:-

It sounds like the dataservice could either be not contactable / offline; too busy or it could even be throwing an exception itself and returning a data response that you are not expecting to receive, that then triggers an exception and crash in your application as your always expecting an exact response without catering for any abnormal responses / events.

If you are contacting an external service over the internet it may just be your internet connection is slow / faulty and not returning the information fast enough as other possibilities.

In your code you are assuming that you always get a response from the server - and that this response will always be of an anticipated structure that your expecting to decode - without factoring in any possibility of abnormal responses returned by the dataservice. I have not used ODataClient personally, so not sure how it behaves in the event of maybe no data received / timeout or in your case the dataservice and how it behaves internally in the response to a bad-request etc.

I am assuming an exception would get thrown, and you do get your debug line executed indicating a failure.

You may want to also adjust this statement so that you write out the exception as well, i.e.:-

private void GetDataFromOdataService ()
{
    try 
    {
        Customers = mODataClient.For ("Customers").FindEntries ();
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("ERROR!" + ex.ToString());
    }
}

If there was a bad response, then the line at Customers = ..... would throw the exception as there may be no Customers returned or some other information packaged in the response from the dataservice.

The Customers variable would also be null at this point I am assuming due to this failing.

So when you get back to your code at foreach (var customers in Customers) { it will then throw a null reference exception as Customers is infact null.

As all your current code executes in the constructor without any try and catch block around this, it will also crash your application at this point as well.

Also you are doing all of this work in the constructor. Try seperating this out. I haven't investigated exactly where the constructor gets called in an iOS page life-cycle, however, if it is in the viewDidLoad, then you have something like 10 seconds for everything to complete, otherwise it will exit automatically. I imagine in your case, this isn't applicable however.

Going forward also try putting your layout controls in the constructor, and move your data task to maybe the OnAppearing override instead.

Using async would definitely be advisable as well, but remember you need to inspect the response from your dataservice, as the error could be embedded within the response also and you will need to detect when it is OK to process the data.

valdetero
  • 4,624
  • 1
  • 31
  • 46
Pete
  • 4,746
  • 2
  • 15
  • 21
  • Thanks a lot Pete. Your reply is awesome and very informative – casillas Oct 09 '14 at 17:08
  • 1
    Hopefully it will help you get this working. If your still having issues and the dataservice is on the internet, then maybe send across the project and I will quickly run it to help? My contact details are on my Profile. – Pete Oct 09 '14 at 17:10
  • Once you have time, could you please take a look the following question: http://stackoverflow.com/questions/26286524/rotating-label-with-databinding-xamarin – casillas Oct 09 '14 at 19:33