Behnam
Behnam

Reputation: 191

For Loop inside Template Literals?

Is it a way to loop inside Template Literals? Obviously this could be done by mapping an array like this:

array = ["a", "b", "c"]
console.log(`foo ${array.map(i => i).join(" ")} bar`)
///foo a b c bar

But what if we need to loop somthing for specific times? like this:

`foo ${for (let i = 0; i <= 10; i++) {Somthing}} bar`

Upvotes: 18

Views: 25099

Answers (6)

SlugFiller
SlugFiller

Reputation: 1874

You can use a tagged template that processes generators. It would save the need to create and return a temporary variable, but you're still technically using IIFE (kinda, since you're not doing the invoking manually).

function tmpl(strings, ...args) {
    let ret = strings[0];
    let index = 0;
    for (const arg of args) {
        if ('GeneratorFunction' === arg.constructor.name) {
            for (const part of arg()) {
                ret += part;
            }
        }
        else {
            ret += arg;
        }
        ret += strings[++index];
    }
    return ret;
}

console.log(tmpl`foo ${ function*() {
    for (let i = 0; i <= 3; i++) {
        yield `(${ i })`;
    }
} } bar`);
// Output: foo (0)(1)(2)(3) bar

Note: This only processes generators, not iterators or arrays. Those are already expression-like, and you can just use .join.

Upvotes: 0

Diego Ven&#226;ncio
Diego Ven&#226;ncio

Reputation: 6007

If you are using angular/typescript, you can do it inside back ``:

  <table class="table">
    <thead style="color: darkred; font-weight: bolder; font-size:22px">
      <tr>
        <th scope="col">Name</th>
        <th scope="col">Age</th>
      </tr>
    </thead>
    <tbody style="font-weight: bolder; font-size:16px">
          ${
        (function myfunction() {
          let test: string[] = []
          for (let item of YourList) {
            
            test.push(
           `<tr>
            <td>${item.name}</td>
            <td>${item.age}</td>
            </tr>`
            )
          }
          return test
        })()
        }

    </tbody>
  </table>

Upvotes: 0

Jodie themathgenius
Jodie themathgenius

Reputation: 21

const tplFor=(statement,body)=>[...(function*(){}).constructor(`for(${statement})yield\`${body}\``)()].join("");

and then in your template do ${tplFor("const person of people","hello! ${person.firstName}")}

Upvotes: 0

ImLuctor
ImLuctor

Reputation: 11

It would be better to implement your function outside the backtick expression like this:

function helloworld() {

let string;

for(let i = 0; i <10 ; i++){
string = 'Hello World!'    
} 
   return string
}

//Inside the backtick

`${helloworld()}`

Upvotes: 1

Amarnath Reddy Dornala
Amarnath Reddy Dornala

Reputation: 189

You can use reducer to achieve in ES6

const anArray = [
  {
    "name": "pulha",
    "as": "puli"
  },
  {
    "name": "puli",
    "as": "moka"
  },
    {
    "name": "moka",
    "as": "starbucks"
  },
  {
    "name": "starbucks",
    "as": "sweet"
  },
    {
    "name": "sweet",
    "as": "krispey"
  },
  {
    "name": "krispey",
    "as": "free"
  }
];

$('#an-example-showing-template').append(`
  ${anArray.reduce((updated, latest) => updated.concat(`<li>${latest.name} alias ${latest.as}</li>`), '')}
`)
#an-example-showing-template > li {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="an-example-showing-template"></ul>

Upvotes: 7

Roberto Zvjerković
Roberto Zvjerković

Reputation: 10137

You can just use an IIFE there:

`foo ${(function fun() {
  // Do your loop here
  // Return the result as a string
})()} bar`

I would advise against it and just create the normal function, call it, assign the return value to a variable and use the variable inside template literal placeholder.

Upvotes: 15

Related Questions