2

I am having trouble recreating and imagining how to recreate the following piece of vanilla Javascript code in Angular2 (I just typed it out on the spot so don't worry about syntax or logic errors). As you can see, I am looping through an array of products and if the iteration modulus of 4 then I close the div with class 'row' and start a new div with a class of row. This is so I can add 'col-xs-3 col-sm-3 col-md-3 col-lg-3' classes onto the products to make them responsive.

<div class='row'>
    <script>
        var html = '';
        for(let i = 0; i < products.length; i++) {
            html += '<div class=`product`>dom code in hhere</div>';
            if(i % 4 === 0) {
                html += '</div><div class=`row`>'
            }
        }
    </script>
<div>

This is easy enough to do in Vanilla and jQuery but in Angular I believe you cannot have an if clause not on an element so I cannot close the row div and start a new one. Here is my code so far:

<div class='row'>
        <div *ngFor='let product of products; let i = index' class='col-xs-1 col-sm-2 col-md-3 col-lg-3'>
            <div class='product'>
                <div class='image'>
                    <img [src]="product.image" />
                </div>
                <div class='info'>
                    <h4 class='title'>{{ product.name }}</h4>
                </div>
            </div>
        </div>
    </div>

So, as you can see, I want to close off the parent '' element on every fourth product and start a new row. I have thought about using a pipe but I still couldn't think of how to utilise this properly.

Can anyone help me here? Thanks

James
  • 2,800
  • 7
  • 45
  • 81
  • It's really difficult to try to implement this the same way as you would in jQuery as Anguar is completely different. I would instead look at having a nested iteration where you would hard code the inner iteration to stop at 4. – Per Feb 07 '17 at 18:05
  • Ok, so for each row you want four products? I would probably `slice` the products into groups of four first, then `push` them into a new array, then have two *ngFor-loops, one looping over the rows and another for the columns. – unitario Feb 07 '17 at 18:17

1 Answers1

4

I'll expand on my comment, it is really easy, you should manipulate the data before sending it to the template:

groupProductList() {
  for(let i = 1; i < 100; i = i + 4) {
    let group = this.productList.slice(i, i + 4);
    this.productListGrouped.push(group);
  }

Then in the template:

<div class="row" *ngFor="let group of productListGrouped; let i = index">
  <div class="col" *ngFor="let product of productListGrouped[i]">
    {{ product.id }}
    {{ product.name }}
  </div>
</div>

Se working Plunkr.

unitario
  • 6,295
  • 4
  • 30
  • 43
  • Great, I was almost there but good to see I was on the right lines! – James Feb 08 '17 at 09:53
  • Nice! Angular becomes very easy once you wrap your brain around the fundamental concepts like component interaction, observables, change detection, etc. but up until that point there will be some frustration to say the least ... – unitario Feb 08 '17 at 10:15
  • Yes been using it for a few years now and it's great but for some reason I was still thinking in terms of vanilla DOM manipulation when tackling this particular problem. Thanks for your answer :) – James Feb 08 '17 at 10:54