AngularJS – Custom filter – toBoolean

Problématique

Aujourd’hui un collègue était en train de jouer avec AngularJS et Tapestry (oui les deux en même temps). Il rencontre un problème où des booléens sont parfois sous la forme booléen (true ou false), parfois sous forme de string (« true » ou « false »), ils valent parfois null et parfois undefined.

Premier reflexe, mettre une condition ternaire dans le HTML : {{ (myBool === ‘true’ || myBool === true) ? ‘\u2713’ : ‘\u2718’ }}

Seulement voilà, quand il y a plein de booléens dans l’application ça devient lourd à gérer.

Surtout quand le stagiaire, et dieu sait que nos stagiaires sont plutôt doués, vient t’annoncer qu’il a introduit des booléens sous forme de nombres entiers (1 ou 0) et qu’il faut revoir ton expression ternaire PARTOUT.

Bref c’est là où tu te dis qu’il y a sûrement plus sage à faire.

Je vous propose donc de rencontrer, à travers un exemple bidon, les custom filters d’AngularJS pour répondre à notre besoin.

controllers.js

Préparation du contrôlleur qui mettra vous permettra de vérifier que le filter correspond bien à vos attentes. Un test unitaire pourrait également être envisagé à ces fins.

'use strict';
 
/* Controllers */
var dumyExampleControllers = angular.module('dumyExampleControllers', []);
 
dumyExampleControllers.controller('DummyCtrl', ['$scope',
	function($scope) {
		$scope.boolTrueValue = true;
		$scope.stringTrueValue = 'true';
		$scope.intTrueValue = 1;
		$scope.boolFalseValue = false;
		$scope.stringFalseValue = 'false';
		$scope.intFalseValue = 0;
		$scope.nullValue = null;
		$scope.undefinedValue = undefined;
	}]);

filters.js

Création du filter toBoolean qui prend input en entrée et qui retourne un booléen.

'use strict';
 
/* Filters */
angular.module('dumyExampleFilters', []).filter('toBoolean', function() {
  return function(input) {
    return input === true || input === 'true' || input === 1 || input === '1' || input === 'yes';
  };
});

partial-dummy.html

Le template fait passer chaque variable du scope par le filter « toBoolean » et affiche ok si elle est considérée comme vraie, sinon nok.

boolTrueValue :    {{ (boolTrueValue    | toBoolean) ? 'ok' : 'nok' }}<br/>
stringTrueValue:   {{ (stringTrueValue  | toBoolean) ? 'ok' : 'nok' }}<br/>
intTrueValue :     {{ (intTrueValue     | toBoolean) ? 'ok' : 'nok' }}<br/>
boolFalseValue :   {{ (boolFalseValue   | toBoolean) ? 'ok' : 'nok' }}<br/>
stringFalseValue : {{ (stringFalseValue | toBoolean) ? 'ok' : 'nok' }}<br/>
intFalseValue :    {{ (intFalseValue    | toBoolean) ? 'ok' : 'nok' }}<br/>
nullValue :        {{ (nullValue        | toBoolean) ? 'ok' : 'nok' }}<br/>
undefinedValue :   {{ (undefinedValue   | toBoolean) ? 'ok' : 'nok' }}<br/>

Résultat

Résultat concluant :

boolTrueValue : ok
stringTrueValue: ok
intTrueValue : ok
boolFalseValue : nok
stringFalseValue : nok
intFalseValue : nok
nullValue : nok
undefinedValue : nok

Complément pour les plus friands

Pour ceux qui veulent encore manger du Javascript je vous propose également les tests unitaires du filter toBoolean.

'use strict';
/* jasmine specs for filters go here */
describe('filter', function() {
 
	beforeEach(module('dumyExampleFilters'));
 
	describe('toBoolean', function() {
		it('should convert any values to boolean correctly', inject(function(toBooleanFilter) {
			expect(toBooleanFilter(true)).toBe(true);
			expect(toBooleanFilter('true')).toBe(true);
			expect(toBooleanFilter(1)).toBe(true);
			expect(toBooleanFilter(false)).toBe(false);
			expect(toBooleanFilter('false')).toBe(false);
			expect(toBooleanFilter(0)).toBe(false);
			expect(toBooleanFilter(null)).toBe(false);
			expect(toBooleanFilter(undefined)).toBe(false);
		}));
	});
});
Tagués avec : , , , ,
Publié dans AngularJS

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*