Javascript TIPS : typer et étendre du JSON

J'inaugure avec cet article une série d'astuces qui facilitent la vie en javascript.
Le but de ce poste est de vous montrer comment étendre et typer du json en javascript. Il est plus que courant de récupérer et manipuler du JSON de nos jours. C'est vrai que ce format à beaucoup d'avantages :

  • léger
  • facilement compréhensible par un humain
  • se compresse très bien
  • un arbre facile à manipuler

Le seul soucis que l'on peut rencontrer c'est que parfois on aimerait avoir à la place d'un arbre d'objets, un arbre avec des types connus :

serait plus sympathique sous la forme :

  • json : MaCollection
    • crs : TypeCrs
    • features :
    • 0: Feature
    • 1: Feature
    • 2: Feature

Au delà du typage qui a un intérêt limité dans cet exemple c'est surtout la capacité d'avoir des méthodes dans nos objets typés qui nous intéresse.

Pour réaliser cela nous allons donc recopier l'objet json dans un objet typé qui aura des méthodes permettant de manipuler plus facilement notre flux json.

Exemple

Pour cet exemple j'utilise un flux json open data : la liste des défibrillateurs de la ville de Montpellier.
Le flux est disponible ici

Les données opendata sont une mine d'information, très pratique pour construire des exemples de la "vraie vie" https://www.data.gouv.fr

// On crée un construteur pour notre type qui prend en paramètre un objet json non typé
function FeatureCollection(jsonObject) {  
    if (!jsonObject) {
        throw 'jsonObject can\'t be null';
    }

    //copie de toutes les propriétés json dans notre objet "typé"
    for (var prop in jsonObject) {
        //on utilise hasOwnProperty pour ne copier que les propriétés de l'objet json et non les propriétés de base des objets javascript tel toString
        if (jsonObject.hasOwnProperty(prop)) {
            this[prop] = jsonObject[prop];
        }
    }
}

A partir d'ici si on crée une instance de FeatureCollection, on se retrouve avec les mêmes propriétés que notre objet json de départ.

On va maintenant étendre notre objet FeatureCollection grâce au prototypage :

FeatureCollection.prototype =  
{
    //Permet de retrouver un défibrillateur en fonction d'un nom de lieu via une recherche de type contient 
    find: function (name) {
        if (!name)
            return this.features;
        return $.grep(this.features, function(feature, index) {
            return feature.properties.nom.toLowerCase().indexOf(name.toLowerCase()) >= 0;
        });
    }
};

Enfin on peut récupérer les données depuis le site open data et par exemple rechercher les défibrillateurs présents dans les piscines de Montpellier.

var openDataUrl = 'https://inspire.data.gouv.fr/api/geogw/services/55d1f9f32984a74b70f3cd07/feature-types/ms:mmm_defibrillateurs/download?format=GeoJSON&projection=WGS84'; 

$.getJSON(openDataUrl, function (json) {
    var defibrilator = new FeatureCollection(json);
    var result = defibrilator.find('piscin');
});

j'ai utilisé jQuery "$.getJSON" pour récupérer le flux opendata et le convertir directement en JSON.

Voila, vous pouvez maintenant étendre facilement vos objets JSON.

L'exemple complet est disponible sur Github