Defer Execution for Es6 Template Literals

Defer execution for ES6 Template Literals

I can see three ways around this:

  • Use template strings like they were designed to be used, without any format function:

    console.log(`Hello, ${"world"}. This is a ${"test"}`);
    // might make more sense with variables:
    var p0 = "world", p1 = "test";
    console.log(`Hello, ${p0}. This is a ${p1}`);

    or even function parameters for actual deferral of the evaluation:

    const welcome = (p0, p1) => `Hello, ${p0}. This is a ${p1}`;
    console.log(welcome("world", "test"));
  • Don't use a template string, but a plain string literal:

    String.prototype.format = function() {
    var args = arguments;
    return this.replace(/\$\{p(\d)\}/g, function(match, id) {
    return args[id];
    });
    };
    console.log("Hello, ${p0}. This is a ${p1}".format("world", "test"));
  • Use a tagged template literal. Notice that the substitutions will still be evaluated without interception by the handler, so you cannot use identifiers like p0 without having a variable named so. This behavior may change if a different substitution body syntax proposal is accepted (Update: it was not).

    function formatter(literals, ...substitutions) {
    return {
    format: function() {
    var out = [];
    for(var i=0, k=0; i < literals.length; i++) {
    out[k++] = literals[i];
    out[k++] = arguments[substitutions[i]];
    }
    out[k] = literals[i];
    return out.join("");
    }
    };
    }
    console.log(formatter`Hello, ${0}. This is a ${1}`.format("world", "test"));
    // Notice the number literals: ^ ^

Resolving template literals at a later context

Template literals are exactly that: Literals. They're evaluated as of where they appear, like all literals. They aren't objects, you can't pass them around.

What you can do instead is put them inside a function and pass the function around. Have the function accept the things the template needs, and return the result of evaluating it.

In your case, you just change blog_entry_template to an arrow function, and call it:

var blog_entries_dom = 'blog_entries';
var blog_entries = [
{
"title": "Hello World",
"id": 2,
"body": "<p>Hello World</p>"
},
{
"title": "World Hello",
"id": 3,
"body": "<p>World Hello</p>"
}
];

var blog_entry_template = item => `<div class="post-preview">
<a href="post.html">
<h2 class="post-title">
${item.title}
</h2>
<h3 class="post-subtitle">
${item.body}
</h3>
</a>
<p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p>
</div>
<hr>`;

var populate_children = function (element_id, objects_list, template) {

var element = document.getElementById(element_id);

var html = '';

for (var i = 0; i < list.length; i++) {
html += template(list[i]);
}

element.innerHTML = html;
};

Usage:

populate_children("some-id", blog_entries, blog_entry_template);

Handling passing variable with template string where value is out of scope

You can create a generic function and pass 3 parameters:

const updateQuery = (table, column, value) =>{
return `UPDATE ${table} SET ${column} = ${value}`;
}

In order to avoid sql-injection you need to use Parameterized query:

One syntax for example:

UPDATE ${table} SET ${column} = ?, [${value}]

You can find more info about it here

ES6 Template Literals: How to pass a scope before they are interpreted?

String literals are evaluated immediately. They cannot be used as templates to be formatted later (Unlike for example Python's format strings that look similar).

You could do what Leonid Beschastny suggests and use little functions that does the interpolation for you.

Something like this:

const error = {
1001: () => 'No token',
1002: (args) => `${args[1]}`,
1003: (args) => `${args[1]} ! ${args[2]}`,
1004: () => 'Missing data'
};
this.error = error[code](arguments);

Template literals and parentheses-less function calls

In the second code snippet, these are logged:

// str
[
"Hello World ",
" ",
" ",
" and more"
]

// values
[
"John",
"John",
3
]

If by those "empty strings" you mean the 2nd and 3rd item of the str array, they are not empty strings; they are strings with a single space. They come from the spaces between the expressions in the template literal:

showstring`Hello World ${name} ${name} ${1 + 2} and more`;
// ^ ^

When a template literal is preceded by an expression – in this case showstring – it's called a tagged template.

In your showstring function, str contains always one more item than the values array. E.g. take a look at what these log:

const showstring = (str, ...values) => {
console.log(str);
console.log(values)
}
const name = 'John'
showstring``;
showstring`${name}`;
showstring`Hello ${name}!`;

es6 template literal in not supporting in firefox browser?

This is not caused by template literals, this is caused by non-standard date formatting.

In a Firefox Developer's Edition 56 Scratchpad window:

(new Date(`${d}-${m}-${y}`)).toString()

/*
Invalid Date
*/

(new Date(`${y}-${m}-${d}`)).toString()

/*
Mon May 04 2015 17:00:00 GMT-0700 (Pacific Standard Time)
*/

Here, using the format DD-MM-YYYY is invalid. However, using a standard format of YYYY-MM-DD produces a valid date.

It appears that Chrome may allow additional formats beyond the standard. It is not advised to use non-standard formats since they are not guaranteed to be supported by all major browsers.

Is there a way to re-use a template literal in Javascript?

Simply make it to be returned by a function:

let int;let temp= () => `Number is: ${int}`;console.log(temp())// Number is: undefinedint = 1;console.log(temp())// Number is: 1int = 2;console.log(temp())// Number is: 2


Related Topics



Leave a reply



Submit