Handling undefined/null values in context object for string templates, replacing with empty string.
This commit is contained in:
parent
4deccae711
commit
38144f84a3
|
@ -12,15 +12,16 @@
|
|||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"handlebars": "^4.7.6"
|
||||
"handlebars": "^4.7.6",
|
||||
"lodash": "^4.17.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^26.6.3",
|
||||
"rollup": "^2.36.2",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-node-builtins": "^2.1.2",
|
||||
"rollup-plugin-node-globals": "^1.4.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"typescript": "^4.1.3",
|
||||
"jest": "^26.6.3"
|
||||
"typescript": "^4.1.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
class Postprocessor {
|
||||
constructor(name, fn) {
|
||||
this.name = name
|
||||
this.fn = fn
|
||||
}
|
||||
}
|
|
@ -6,6 +6,12 @@ const {
|
|||
includesAny,
|
||||
} = require("../utilities")
|
||||
|
||||
const PreprocessorNames = {
|
||||
SWAP_TO_DOT: "swap-to-dot-notation",
|
||||
HANDLE_SPACES: "handle-spaces-in-properties",
|
||||
FINALISE: "finalise",
|
||||
}
|
||||
|
||||
class Preprocessor {
|
||||
constructor(name, fn) {
|
||||
this.name = name
|
||||
|
@ -20,7 +26,7 @@ class Preprocessor {
|
|||
}
|
||||
|
||||
const PROCESSORS = [
|
||||
new Preprocessor("swap-to-dot-notation", statement => {
|
||||
new Preprocessor(PreprocessorNames.SWAP_TO_DOT, statement => {
|
||||
let startBraceIdx = statement.indexOf("[")
|
||||
let lastIdx = 0
|
||||
while (startBraceIdx !== -1) {
|
||||
|
@ -34,7 +40,7 @@ const PROCESSORS = [
|
|||
return statement
|
||||
}),
|
||||
|
||||
new Preprocessor("handle-spaces-in-properties", statement => {
|
||||
new Preprocessor(PreprocessorNames.HANDLE_SPACES, statement => {
|
||||
// exclude helpers and brackets, regex will only find double brackets
|
||||
const exclusions = HelperFunctions.concat(["{{", "}}"])
|
||||
// find all the parts split by spaces
|
||||
|
@ -62,7 +68,7 @@ const PROCESSORS = [
|
|||
return statement.replace(/\[\[/g, "[").replace(/]]/g, "]")
|
||||
}),
|
||||
|
||||
new Preprocessor("finalise", statement => {
|
||||
new Preprocessor(Preprocessor.FINALISE, statement => {
|
||||
let insideStatement = statement.slice(2, statement.length - 2)
|
||||
if (insideStatement.charAt(0) === " ") {
|
||||
insideStatement = insideStatement.slice(1)
|
||||
|
@ -74,7 +80,7 @@ const PROCESSORS = [
|
|||
insideStatement = `(${insideStatement})`
|
||||
}
|
||||
return `{{ all ${insideStatement} }}`
|
||||
})
|
||||
}),
|
||||
]
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,10 @@ const HELPERS = [
|
|||
}),
|
||||
// this help is applied to all statements
|
||||
new Helper(HelperFunctionNames.ALL, value => {
|
||||
// null/undefined values produce bad results
|
||||
if (value == null) {
|
||||
return ""
|
||||
}
|
||||
let text = new SafeString(unescape(value).replace(/&/g, "&"))
|
||||
if (text == null || typeof text !== "string") {
|
||||
return text
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
const handlebars = require("handlebars")
|
||||
const { registerAll } = require("./helpers/index")
|
||||
const { preprocess } = require("./custom/preprocessor")
|
||||
const { cloneDeep } = require("lodash/fp")
|
||||
const { removeNull } = require("./utilities")
|
||||
|
||||
const hbsInstance = handlebars.create()
|
||||
registerAll(hbsInstance)
|
||||
|
@ -78,6 +80,8 @@ module.exports.processObjectSync = (object, context) => {
|
|||
* @returns {string} The enriched string, all templates should have been replaced if they can be.
|
||||
*/
|
||||
module.exports.processStringSync = (string, context) => {
|
||||
const clonedContext = removeNull(cloneDeep(context))
|
||||
// remove any null/undefined properties
|
||||
if (typeof string !== "string") {
|
||||
throw "Cannot process non-string types."
|
||||
}
|
||||
|
@ -85,7 +89,7 @@ module.exports.processStringSync = (string, context) => {
|
|||
string = preprocess(string)
|
||||
// this does not throw an error when template can't be fulfilled, have to try correct beforehand
|
||||
template = hbsInstance.compile(string)
|
||||
return template(context)
|
||||
return template(clonedContext)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,3 +13,15 @@ module.exports.swapStrings = (string, start, length, swap) => {
|
|||
module.exports.includesAny = (string, options) => {
|
||||
return options.some(option => string.includes(option))
|
||||
}
|
||||
|
||||
// removes null and undefined
|
||||
module.exports.removeNull = obj => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj)
|
||||
.filter(([key, value]) => value != null)
|
||||
.map(([key, value]) => [
|
||||
key,
|
||||
value === Object(value) ? module.exports.removeNull(value) : value,
|
||||
])
|
||||
)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,14 @@ describe("Test that the string processing works correctly", () => {
|
|||
}
|
||||
expect(error).not.toBeNull()
|
||||
})
|
||||
|
||||
it("confirm that null properties are handled correctly", async () => {
|
||||
const output = await processString("hello {{ name }} I am {{ name2 }}", {
|
||||
name: undefined,
|
||||
name2: null,
|
||||
})
|
||||
expect(output).toBe("hello I am ")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Test that the object processing works correctly", () => {
|
||||
|
|
|
@ -2799,7 +2799,7 @@ lodash.sortby@^4.7.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
|
||||
|
||||
lodash@^4.17.19:
|
||||
lodash@^4.17.19, lodash@^4.17.20:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
|
|
Loading…
Reference in New Issue