Skip to content

Instantly share code, notes, and snippets.

@bravo-kernel
Last active September 23, 2019 10:51
Show Gist options
  • Select an option

  • Save bravo-kernel/933d334c4866caacd29420efd14cf472 to your computer and use it in GitHub Desktop.

Select an option

Save bravo-kernel/933d334c4866caacd29420efd14cf472 to your computer and use it in GitHub Desktop.
Feathers: converting 0/1 to booleans (and vice versa). See comment for an explanation.
// Application hooks that run for every service
const { disallow } = require('feathers-hooks-common');
const log = require('./hooks/log');
const castResultIntegersToBoolean = require('./hooks/cast-result-integers-to-boolean');
const castQueryParamBooleansToInteger = require('./hooks/cast-query-param-booleans-to-integer');
// import uncastQueryParamBooleans from ('./hooks/uncast-query-param-booleans');
module.exports = {
before: {
all: [
castQueryParamBooleansToInteger(),
log()
],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: [],
},
after: {
all: [log()],
find: [castResultIntegersToBoolean()],
get: [castResultIntegersToBoolean()],
create: [castResultIntegersToBoolean()],
update: [castResultIntegersToBoolean()],
patch: [castResultIntegersToBoolean()],
remove: [],
},
error: {
all: [log()],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: [],
},
};
// After hook that casts query parameters to Integer if the parameter name
// starts with `is`, `has` or `can` AND is followed by a Capitalcharacter so
// that e.g. `isFavorite: true` becomes `isFavorite: 1`.
const REGEX_BOOLEAN_FIELD = /^is[A-Z]|^has[A-Z]|^can[A-Z]/;
// eslint-disable-next-line no-unused-vars
module.exports = () => {
return async context => {
const queryParams = context.params.query;
// as is the case with internal use (e.g. a get() from within a hook)
if (queryParams === undefined) {
return context;
}
// as is the case with external use
if (Object.entries(queryParams).length === 0) {
return context;
}
context.params.query = castToIntegers(queryParams);
return context;
};
};
function castToIntegers(params) {
const result = {};
for (const [key, value] of Object.entries(params)) {
if (REGEX_BOOLEAN_FIELD.test(key)) {
result[key] = value === 'true' ? 1 : 0;
} else {
result[key] = value;
}
}
return result;
}
// After hook that casts field values to Javascript Boolean if the field name
// starts with `is`, `has` or `can` AND is followed by a Capitalcharacter so
// that e.g. `isFavorite: 1` becomes `isFavorite: true`.
const { getItems, replaceItems } = require('feathers-hooks-common');
const REGEX_BOOLEAN_FIELD = /^is[A-Z]|^has[A-Z]|^can[A-Z]/;
// eslint-disable-next-line no-unused-vars
module.exports = () => {
return async context => {
const items = getItems(context);
const isArray = Array.isArray(items);
if (isArray) {
const newItems = [items.map(castToBooleans)];
replaceItems(context, newItems[0]);
}
if (isArray === false) {
const newItems = castToBooleans(items);
replaceItems(context, newItems);
}
return context;
};
};
function castToBooleans(item) {
const result = {};
for (const [key, value] of Object.entries(item)) {
if (REGEX_BOOLEAN_FIELD.test(key)) {
result[key] = !!value;
} else {
result[key] = value;
}
}
return result;
}
@bravo-kernel

Copy link
Copy Markdown
Author

When using Feathersjs with Sequelize MySQL and raw: true all booleans will appear as 0/1 to your clients. These hooks will:

  • convert 0/1 to true/false in the json response
  • convert incoming query params true/false to 0/1

make sure to change the REGEX for your needs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment