I’m using the Mustache template which renders the JSON onto the page. Same set up for those who helped with previous threads, thanks in advance.
For an example
name: Luke Skywalker
Now when I create a function and change this, everything works
{{#formatString}}{{name}}{{/formatString}}
luke-skywalker
Now if I call/display the name again without the function, the name is still showing as luke-skywalker. I think it has something to do with this.name though could be mistaken.
Code
function formatString(str) {
return str.replace(/\s+/g, '-').toLowerCase();
}
function formatStringTwo(str) {
return str.replace(/\s+/g, '+').toLowerCase();
}
var renderFuncs = {
'formatString': function () {
return function (text, render) {
this.name = formatString(this.name);
return render(text);
};
},
'formatStringTwo': function () {
return function (text, render) {
this.name = formatStringTwo(this.name);
return render(text);
};
}
}
You’re modifying the original data here. After this line
$.extend(data, renderFuncs)
your data object looks something like this
{
name: 'Luke Skywalker',
// ...
formatString: function () {
// This function gets called first...
return function (text, render) {
// this.name is "Luke Skywalker"
this.name = formatString(this.name)
// this.name is now "luke-skywalker"
return render(text)
}
},
formatStringTwo: function () {
// Then this function gets called...
return function (text, render) {
// this.name is still "luke-skywalker",
// so /\s+/ has no match
this.name = formatStringTwo(this.name)
return render(text)
}
}
}
Instead you’ll just have to return the formatted text value without mutating anything:
var renderFuncs = {
formatString: function () {
return function (text, render) {
return formatString(render(text))
}
},
formatStringTwo: function () {
return function (text, render) {
return formatStringTwo(render(text))
}
}
}
Initially, what you suggest is what I was using some time back. On an older thread I was trying to format a date object which would only work by adding, what we have just removed (below snippet), this fixed the issue after much trail and error. I carried on using this technique ever since.
Maybe this was just need to format the date.
formatDate: function () {
var format = "DD-MM-YYYY";
return function (text, render) {
this.submitted = dateConvert(new Date(this.submitted), format);
return '<b>' + render(text) + '</b>';
};
}
That’s the history behind me using this anyhow
What you suggest is working perfect now
I’ll have to run a few more tests and add the date into the mix and see what happens.
Well no, that solution is not quite right either I’m afraid… it may work in this case but again, it modifies the data. So it should actually like this:
Mustache.render(template, {
submitted: '2018-03-06T12:01:00',
formatDate: function () {
return function (text, render) {
var format = 'DD-MM-YYYY'
var rendered = render(text).trim()
var date = new Date(rendered)
return dateConvert(date, format)
}
}
})
If you do want to modify the data, you’d do so beforehand so you get no surprises later on. For example, $.enxtend()ing it with render functions is okay because the data object gets discarded after the render process anyway. You could also explicitly prepare the data like so:
But a render function itself should never do this (be it in mustache, react, vue or what have you); given the same data, it should always yield the same output no matter how often or at which point it gets called.