Handling undefined/null values in context object for string templates, replacing with empty string.

This commit is contained in:
mike12345567 2021-01-21 13:48:23 +00:00
parent 4deccae711
commit 38144f84a3
8 changed files with 50 additions and 9 deletions

View File

@ -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"
}
}

View File

@ -0,0 +1,6 @@
class Postprocessor {
constructor(name, fn) {
this.name = name
this.fn = fn
}
}

View File

@ -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} }}`
})
}),
]
/**

View File

@ -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

View File

@ -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)
}
/**

View File

@ -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,
])
)
}

View File

@ -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", () => {

View File

@ -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==