Last active
November 17, 2019 00:13
-
-
Save dfkaye/68dc3c925ae153a916ad56a7fc4d7f3c to your computer and use it in GitHub Desktop.
derive state from selectors (filters)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 4 June 2019 | |
// ES5 version of create and test taken from Nick Scialli's articl, | |
// "Calculating Derived State in JavaScript Using Selectors" | |
// @see https://nick.scialli.me/calculating-derived-state-in-javascript-using-selectors/ | |
function createSelector(functions) { | |
var len = arguments.length; | |
if (!len || (len == 1 && typeof functions == 'function')) { | |
throw new SyntaxError("expects more than one function: " + functions); | |
} | |
var funcs = len > 1 ? [].slice.call(arguments) : [].slice.call(functions) | |
var last = funcs.length > 1 ? funcs.pop() : null; | |
return function(state) { | |
var inputs = funcs.map(function(func) { | |
return func(state); | |
}); | |
return last ? last.apply(0, inputs) : inputs; | |
}; | |
}; | |
/* test it out */ | |
function allowed(who) { return who.age >= 21 || who.employee; } | |
function friendly(who) { return who.isFriendly; } | |
function both(allowed, friendly) { return allowed && friendly; } | |
var testVarArgs = createSelector(allowed, friendly, both); | |
var testVarArray = createSelector([ allowed, friendly, both ]); | |
var tests = [ | |
{ | |
name: "TTT", | |
age: 22, | |
employee: true, | |
isFriendly: true | |
}, | |
{ | |
name: "TTF", | |
age: 22, | |
employee: true, | |
isFriendly: false | |
}, | |
{ | |
name: "TFT", | |
age: 22, | |
employee: false, | |
isFriendly: true | |
}, | |
{ | |
name: "TFF", | |
age: 22, | |
employee: false, | |
isFriendly: false | |
}, | |
{ | |
name: "FTT", | |
age: 19, | |
employee: true, | |
isFriendly: true | |
}, | |
{ | |
name: "FFT", | |
age: 19, | |
employee: false, | |
isFriendly: true | |
}, | |
{ | |
name: "FTF", | |
age: 19, | |
employee: true, | |
isFriendly: false | |
}, | |
{ | |
name: "FFF", | |
age: 19, | |
employee: false, | |
isFriendly: false | |
} | |
]; | |
console.log( | |
tests.map(test => testVarArgs(test)) | |
); | |
console.log( | |
tests.map(test => testVarArray(test)) | |
); | |
~(function enforcesTwoFunctions() { | |
var testVarOne; | |
var error = 'No errors. All is fine.' | |
try { testVarOne = createSelector(allowed); } | |
catch (e) { | |
error = e | |
} | |
finally { | |
console.error(error); | |
} | |
}()); | |
/* | |
// Should see: | |
// [ true, false, true, false, true, false, false, false ] | |
// [ true, false, true, false, true, false, false, false ] | |
// SyntaxError: "expects more than one function as argument: function allowed(who) { return who.age >= 21 || who.employee; }" | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment