Answered by:
Implementing IListDataAdapter.change

Question
-
I'm creating a custom data source for the ListView but I am having trouble implementing the IListDataAdapter change() method so that I can edit records in the data source. I get the following exception:
Exception was thrown but not handled in user code at line 6691, column 21 in ms-appx://microsoft.winjs.1.0.rc/js/ui.js
0x800a138f - JavaScript runtime error: Unable to set property 'itemNew' of undefined or null referenceThe relevant lines of code are in the onEditComplete() method in the ui.js library:
} else if (edit.editType === EditType.change) { //#DBG _ASSERT(slot.item); slot.itemNew = item; if (!reentrant) { changeSlotIfNecessary(slot); } }
When the onEditComplete() method is called, slot does not have a value and a null reference exception is thrown.
My implementation of the IListDataAdapter.change method looks like this:
change: function(key, changedData, indexHint) { var that = this; return new WinJS.Promise(function (complete, error) { that._ensureData().then(function (data) { var i = that._getIndexFromKey(data.items, key); var changedItem = { key: key, index: indexHint, data: changedData }; data.items[i] = changedItem; that._saveData(data).then(function () { complete(changedItem); }); }); }); },
I've tried both including and not including the indexHint when I return the IItem, but I get the same exception in either case.
Advice here would be appreciated!
-- Stephen
Saturday, July 14, 2012 3:38 PM
Answers
-
Hi Stephen,
Good catch. It seems that topic in the docs for VDS somehow escaped the doc review process, and need some more work. We'll fix them.
It turns out the IListDataSource.change function should return a promise that does not yield a value, so use promise.wrap() or promise.wrap(null). The reason for it returning a promise is to indicate that the datasource has finished the commit for the data, and it was successful. So if you change the code to:
change: function (key, data, indexHint) {
var newItem = {
key: key+"new",
data: data
};
var i = this._getIndexFromKey(key);
this._arrayData[i] = data;
return new WinJS.Promise.wrap(null);
},it should work as expected. The insertXXXX methods return an item so that the datasource can update the item with the key.
Sam
- Marked as answer by S Walther Saturday, July 21, 2012 4:09 AM
Friday, July 20, 2012 9:34 PM
All replies
-
Hi,
Base on my understanding, since it is a complex scenario, it would be better if you can share your demo project to SkyDrive, then we can find the issue conveniently and provide further suggestions for you.
Best Regards,
Ming Xu.
Please mark the replies as answers if they help or unmark if not.
If you have any feedback about my replies, please contact msdnmg@microsoft.com.
Microsoft One Code FrameworkTuesday, July 17, 2012 10:51 AMModerator -
Hi Ming,
Sure -- I have a simple implementation of a custom data source located here:
http://sdrv.ms/Mv1GxR
If you select an item in the ListView and click the Edit button then you get the error described above when the change() method is called.
-- Stephen
Tuesday, July 17, 2012 3:39 PM -
Hi,
In the onEditComplete function, the slot variable is defined in the if branch:
function onEditComplete(item) {
if (item) {
if (keyUpdate && keyUpdate.key !== item.key) {
var slot = keyUpdate.slot;
// …
} else if (edit.editType === EditType.change) {
//#DBG _ASSERT(slot.item);
slot.itemNew = item;
}
}
}
So if you enter the else branch, slot is never defined. Thus you get the error.If you treat it is a bug, you can also report it on http://connect.microsoft.com/visualstudio.
Best Regards,
Ming Xu.
Please mark the replies as answers if they help or unmark if not.
If you have any feedback about my replies, please contact msdnmg@microsoft.com.
Microsoft One Code Framework- Edited by MingXu-MSFTMicrosoft employee, Moderator Wednesday, July 18, 2012 10:58 AM
Wednesday, July 18, 2012 10:58 AMModerator -
Hi Ming,
Is that really the right place to report bugs in WinJS? I only see areas to report bugs on Visual Studio, .NET framework, and Silverlight -- there is no area for submitting a Metro/WinJS bug.
-- Stephen
Wednesday, July 18, 2012 4:46 PM -
Hi Stephen,
I will check this out further for you!
Could you put a complete project up there for me to look at rather than me trying to piece together a repro from your datasource?
-Jeff
Jeff Sanders (MSFT)
Thursday, July 19, 2012 12:27 PMModerator -
Okay, I created an archive named BadChange.zip which includes the project at http://sdrv.ms/Mv1GxR
Select a task and click the Edit button to create the error.
-- Stephen
Thursday, July 19, 2012 5:21 PM -
Hi Stephen,
Good catch. It seems that topic in the docs for VDS somehow escaped the doc review process, and need some more work. We'll fix them.
It turns out the IListDataSource.change function should return a promise that does not yield a value, so use promise.wrap() or promise.wrap(null). The reason for it returning a promise is to indicate that the datasource has finished the commit for the data, and it was successful. So if you change the code to:
change: function (key, data, indexHint) {
var newItem = {
key: key+"new",
data: data
};
var i = this._getIndexFromKey(key);
this._arrayData[i] = data;
return new WinJS.Promise.wrap(null);
},it should work as expected. The insertXXXX methods return an item so that the datasource can update the item with the key.
Sam
- Marked as answer by S Walther Saturday, July 21, 2012 4:09 AM
Friday, July 20, 2012 9:34 PM -
Thanks Sam! Really appreciate the answer. That works great! All of my data sources are working now.
-- Stephen
Saturday, July 21, 2012 4:09 AM