locked
Custom DataSource throws exception when calling insertAtEnd() too fast

    Question

  • I've created a custom data source for IndexedDB by following the Bing data source sample. My IndexedDbDataSource works fine for retrieving data, but I ran into an issue when inserting data. If I call insertAtEnd() slowly then everything works fine. If I call the method over and over again then I get an exception:

    Exception was thrown but not handled in user code at line 7882, column 33 in ms-appx://microsoft.winjs.1.0.rc/js/ui.js
    0x800a138f - JavaScript runtime error: Unable to get property 'getCount' of undefined or null reference

    The exception occurs within the countedCancelation() method in the WinJS.UI library.  The "WinJS.UI.VirtualizedDataSource.resetCount" event is raised but there is no associated data source.

    Within the insertAtEnd() method, I've tried calling both _notificationHandler.invalidateAll() and _notificationHandler.inserted(). Neither seems to help. Is there something else that I need to be doing inside of my insertAtEnd() method?  Here is my code:

    insertAtEnd:function(unused, data) {
        var that = this;
        return new WinJS.Promise(function (complete, error) {
            that.getObjectStore("readwrite").done(function(store) {
                store.add(data).onsuccess = function (evt) {
                    store.get(evt.target.result).onsuccess = function (evt) {
                        var newItem = {
                            key:evt.target.result[store.keyPath].toString(),
                            data:evt.target.result
                        }
                        that._getPreviousItem(newItem.key).done(function (previousItem) {
                            //that._notificationHandler.inserted(
                            //       newItem,
                            //       previousItem[store.keyPath].toString(),
                            //       null,
                            //       null
                            //    );
    
                            that._notificationHandler.invalidateAll();
    
                            complete(newItem);
                        });
                    };
                };
            });
        });
    }
    

    Thanks,

       Stephen

    Sunday, July 08, 2012 6:21 PM

Answers

  • You will want to use beginEdits ....  Insert lots of stuff... then endEdits if you are adding a group of data like that.

    It sounds like you are enterning insertAtEnd async and before the first one completes you are starting another.  You would need to block until you have finished the first insertAtEnd.

    -Jeff


    Jeff Sanders (MSFT)

    • Marked as answer by S Walther Monday, July 09, 2012 8:08 PM
    Monday, July 09, 2012 6:52 PM
    Moderator

All replies

  • Hi Stephen,

    Can you post a siimple project that repros the problem?

    -Jeff


    Jeff Sanders (MSFT)

    Monday, July 09, 2012 12:40 PM
    Moderator
  • Hi Jeff,

    I have not found any samples from Microsoft which show how to implement the insertAtEnd() method (the Bing sample is read only). Do you know of any sample code which shows the correct way to implement insertAtEnd() when creating a custom datasource with a VirtualizedDataSource?

    I'm wondering:

    1) What is the correct way to send notifications?  Should you call notificationHandler.invalidateAll() or are you required to call notificationHandler.inserted()?  

    2) Do I need to update the status somehow?  I see there is a statuschanged event on the VirtualizedDataSource object but I don't know how to trigger it.

    Any advice here would be appreciated (or a link to a full implementation of a custom data source which would work with the ListView control).

      -- Stephen

    Monday, July 09, 2012 5:01 PM
  • Hi Jeff,

    Actually, there is one sample of a custom data source with an insertAtEnd() method, the ListView Working with Data Sources sample. In this sample, neither notification.invalidateAll() nor notification.inserted() is called -- is that the right approach?

    I tried taking out both notification calls from my insertAtEnd() code but the same exception concerning the missing data source for getCount is raised. The exception is only raised when I attempt to add a bunch of new items using insertAtEnd() quickly (I have the insertAtEnd() method wired up to a button). If I click the button slowly then I don't get the exception and the items appear in the ListView control.

      -- Stephen

       

    Monday, July 09, 2012 6:17 PM
  • You will want to use beginEdits ....  Insert lots of stuff... then endEdits if you are adding a group of data like that.

    It sounds like you are enterning insertAtEnd async and before the first one completes you are starting another.  You would need to block until you have finished the first insertAtEnd.

    -Jeff


    Jeff Sanders (MSFT)

    • Marked as answer by S Walther Monday, July 09, 2012 8:08 PM
    Monday, July 09, 2012 6:52 PM
    Moderator
  • Hi Jeff,

    Yep -- that worked. Thanks!

      -- Stephen

    Monday, July 09, 2012 8:08 PM
  • Hi Stephen,

    I'm using your code for the IndexedDbDataSource, and the same exception is thrown when calling remove(key) in rapid succession. Any tip on how to properly do this?

    Thanks!

    Monday, July 23, 2012 6:20 AM
  • Hi sigermti,

    Yes, be sure to call beginEdits() and endEdits() and the issue goes away. If you call remove() too fast without using beginEdits() and endEdits() then a second remove() might start before the first remove() ends and you get concurrency issues.

    document.getElementById("btnDelete").addEventListener("click", function () {
        if (lvMovies.selection.count() == 1) {
            moviesDataSource.beginEdits();
            lvMovies.selection.getItems().done(function (items) {
                moviesDataSource.remove(items[0].key);
                moviesDataSource.endEdits();
            });
        }
    });
    

    Tuesday, July 24, 2012 5:42 AM
  • That makes sense; I'll try shortly. Thanks for your answer and for your blog, it's really helpful.
    Tuesday, July 24, 2012 6:04 AM