Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make function calls with ES6 template literals

UPDATE: Here is a better example; My code is

let myFunction = () => {

    console.log('Yo');
    alert('Yo');

}

let About = {

    render : async () => {

        return /*html*/`
        <h1> About </h1>
        <button id="myBtn" type="button" >Try it</button> 

        <script>
            document.getElementById("myBtn").addEventListener ("click",  ${myFunction})
        </script>
    `
    }
}

export default About;

This transforms to the HTML code;

<div id="page_container" class="container pageEntry">
        <h1> About </h1>
        <button id="myBtn" type="button">Try it</button> 

        <script>
            document.getElementById("myBtn").addEventListener ("click",  () => {

    console.log('Yo');
    alert('Yo');

})
        </script>
    </div>

However on clicking on the button, nothing happens;


I am trying to work on a basic vanilla js SPA and I have hit a problem where I am unable to call any functions in my current module from the html code. I am using the es6 modules by specifying in my index.html that script tag is of type="module".

For example, in this code, i have tried both the inline onclick tag attribute as well as adding an event listener (i used one at a time, not together. showing it here just for illustration)

let myFunction = () => {
    console.log('Yo');
    alert('Yo');
}

let About = {

    render : async () => {

        return /*html*/`
        <h1> About </h1>
        <button id="myBtn" type="button" onclick="${myFunction}">Try it</button> 

        <script>
        document.getElementById("myBtn").addEventListener ("click",  myFunction()})
        </script>
    `
    }
}

export default About;

and I consume the resultant view as

content.innerHTML = await page.render();

from my main module.

The only way I am able to do this is by having my function call return yet another template containng the actual JS code.

let myFunction = () => {
    return `
        alert('Yo');
        document.getElementById('myBtn').textContent = 'Duh'
        `
}

however, this creates a very ugly page where my entire JS code is added inline into the HTML and that I can no longer use double quotes in my js code.

like image 298
Rishav Sharan Avatar asked Oct 09 '18 12:10

Rishav Sharan


People also ask

Are template literals ES6?

Template Literals is an ES6 feature (JavaScript 2015). Template Literals is not supported in Internet Explorer.

What is `` in JS?

Backticks ( ` ) are used to define template literals. Template literals are a new feature in ECMAScript 6 to make working with strings easier. Features: we can interpolate any kind of expression in the template literals. They can be multi-line.

What a template literal can be used for in JavaScript code?

Template literals are literals delimited with backtick (`) characters, allowing for multi-line strings, for string interpolation with embedded expressions, and for special constructs called tagged templates.

What is ES6 template string?

Template literals are a new feature introduced in ECMAScript 2015/ ES6. It provides an easy way to create multiline strings and perform string interpolation. Template literals are the string literals and allow embedded expressions.


2 Answers

Here's how you can invoke a function in a template literal:

const func = () => 'Hello'

console.log(`${func()} World`)
like image 180
Jordan Enev Avatar answered Oct 28 '22 19:10

Jordan Enev


Figured out my problem with the help of another forum.

"Scripts inserted into innerHTML don't run. You should try splitting the render function into render and onMount - the second one called just after the innerHTML line."

Architecting my app into;

let About = {
    render : async () => {
        let view =  /*html*/
            `
            <h1> About </h1>
            <button id="myBtn" type="button" >Try it</button> 
            `
        return view
    },
    after_render: async () => {
        document.getElementById("myBtn").addEventListener ("click",  () => {
            console.log('Yo')
            alert('Yo')
        })
    }

}

export default About;

and consuming it as;

content.innerHTML = await page.render();
await page.after_render();

solved my problems.

like image 5
Rishav Sharan Avatar answered Oct 28 '22 21:10

Rishav Sharan