J’ai eu des bugs sur mes applications WinJS, et je me suis dit que j’allais partager avec vous, parce que vous savez, j’aime bien partager (et puis ça fait plus de 6 mois que j’ai pas blogué, y’a des gens qui risquent de s’inquiéter).

Donc j’ai trouvé 2 bugs, les 2 en rapports avec des listes groupées.

1 – SemanticZoom : “Object doesn’t support property or method ‘itemFromDescription’”

Si vous ne connaissez pas le principe du SemanticZoom, c’est tout simple. Vous avez deux vues : une liste d’éléments, affichés par groupe, et une liste n’affichant que les groupes. À l’utilisation, vous avez votre liste d’éléments, vous faites un zoom arrière (en pinçant les doigts, ou Ctrl+molette) et la liste des groupes apparait. Lorsque vous cliquez sur un groupe vous repassez sur la liste d’éléments, avec le groupe cliqué affiché. C’est le fonctionnement du start menu de Windows 8.

En mettant en place mon contrôle SemanticZoom, j’ai donc eu l’exception suivante : “Object doesn’t support property or method ‘itemFromDescription’”, dont la description ne fournit absolument aucun détail sur l’origine du bug.

Après investigation, j’ai donc trouvé que l’origine venait des identifiants du groupe : ils étaient de type entier. Et ça, le SemanticZoom, il aime pas.

La solution : utiliser des Strings.

var bindingList = new WinJS.Binding.List().createGrouped( 
function(item) { return item.group.id.toString(); }, 
function(item) { return item.group; });

2 – Liste groupée et filtrée : “Unable to get property ‘id’ of undefined or null reference”

Une fois que j’ai réussi à gérer ma liste groupée, j’ai voulu ajouter un filtre. Au lieu d’afficher tous mes items, je décide de n’afficher que mes items favoris.

Pour ça, je peux créer une binding list filtrée, de la manière suivante, en me basant sur la liste précédente.

var bindingList = new WinJS.Binding.List().createGrouped( 
    function(item) { return item.group.id.toString(); }, 
    function(item) { return item.group; } 
);
var filteredList = bindingList.createFiltered( 
    function(item) { return item.isFavorite; } 
);

Et là, encore une fois, j’ai une exception : “Unable to get property ‘id’ of undefined or null reference”. Et encore une fois, l’erreur est très explicite. Comme ce n’est pas le message de l’exception qui va vous aider, je vous dis de suite ce qu’il s’est passé :

En créant la liste, la binding list a récupéré la liste des groupes, en fonction des items présents. Puis lorsque le filtre a été appliqué, on s’est retrouvé avec des groupes vides. Et là paf, exception.

La solution : inverser les appels à createGrouped et createFiltered :

var filteredList = new WinJS.Binding.List().createFiltered( function(item){return item.isFavorite;}); 
var groupedList = filteredList.createGrouped( 
    function(item) { return item.group.id.toString(); }, 
    function(item) { return item.group; } 
);

Ainsi, les groupes sont calculés à partir de la liste déjà filtrée, et tout fonctionne !