0

I want to declare a variable inside a template literal and use it in the same template later is that possible? If this is not possible it seems like a missing feature to me.

const tmp = tag`
 some random text, ${let myvar = 55} more text,
 even more text ${myvar}
`
inux
  • 99
  • 7
  • 4
    Out of curiosity, why would you want to do that? – Abdul Niyas P M Dec 27 '22 at 12:14
  • I mean template literals are good for creating templating languages, so in my case i would create templating language for html with control flow for looping lists, the `let` keyword can be used to initialize multiple variables with comma seperation, so a loop would look something like ```

    ${item + index}

    ```
    – inux Dec 27 '22 at 12:16
  • 2
    I don't think template literals are useful this way the way it might seem at first glance. Say your server delivers you such a template and you've got it in a string. There's not much you can do with it unless you want to use `eval`. Use mustache or handlebars or whatever. – Trevor Dixon Dec 27 '22 at 12:23
  • Otherwise just declare your variables above the template or put it in a function like `const tmp = (input) => { let myvar = input+55; return tag\`${myvar}\`; }` – Trevor Dixon Dec 27 '22 at 12:25
  • @TrevorDixon it can work without eval there are ways. No need for eval. It really seems like a missing feature in template literals – inux Dec 27 '22 at 12:26
  • You could write a parser for templates that have this template literal style, but JS itself won't help you. – Trevor Dixon Dec 27 '22 at 12:27
  • https://stackoverflow.com/questions/30003353/can-es6-template-literals-be-substituted-at-runtime-or-reused – Trevor Dixon Dec 27 '22 at 12:35
  • That's a good duplicate @TrevorDixon voting to close. (also reinforces that one would have to use `eval`) – pilchard Dec 27 '22 at 13:13

1 Answers1

-2

Template literals can literally return only two things:

  • the parts they consist of
  • the values in-between

If you want a variable shared between between different values, they have to be closured
If you want to use some calculation, you have to pass in a function

const tmp = (() => {
  let myvar;
  return tag`
   some random text, ${() => myvar = 55} more text,
   even more text ${() => myvar}
   and the double text ${() => myvar + myvar}
  `
})()
Dimava
  • 7,654
  • 1
  • 9
  • 24
  • Returns `'\n some random text, () => myvar = 55 more text,\n even more text () => myvar\n and the double text () => myvar + myvar\n '` unless `tag` does something smart with the functions instead of converting them to strings. Is that what you were thinking? – Trevor Dixon Dec 27 '22 at 12:40
  • You would need to make each contained function an IIFE to make this work, but in all but the first case the function isn't necessary (and you haven't defined `tag` so who knows what this would return). `\`some random text, ${(() => (myvar = 55))()} more text ${myvar} text ${myvar + myvar}\`` – pilchard Dec 27 '22 at 13:08
  • try ``((...a)=>console.log(...a))` string ${ {value: new Date()} } string ` ``. You should know that template literals call functions with their contents to use them for something more then just strings – Dimava Dec 27 '22 at 21:13