Abdo
Abdo

Reputation: 14071

Check if array is null in nested for loop in CoffeeScript

Consider the following code:

class StoreController
    constructor: ->
      @products = gems

      current_id = 0
      for product in @products
        if product.images?
          for img in product.images
            img.id = current_id
            current_id += 1


gems = [
  {
    name: 'Dodecahedron'
    images: [
        {
            full: "assets/img0.gif"
        }
        {
            full: "assets/img1.gif"
        }
    ]
  }
  {
    name: 'Gemmy Gem'
  }
  {
    name: 'Pentagonal Gem'
  }
]

Is there a better way to write the nested for loops to check for product.images? without that if product.images? line?

EDIT: The accepted answer below does actually answer this question. However, I decided to change the way I am writing my code to use a custom filter instead.

In filter.js.coffee , I wrote the following:

filterMod = angular.module 'storeFilters', []
current_id = 0

filterMod.filter 'addIds', ->
  return (items) ->
    # avoid $rootScope:infdig
    return items if !items? || items.processed

    for img in items
      img.id = current_id
      current_id += 1

    items.processed = true
    return items

The HTML goes below, notice the use of addIds in the inner ng-repeat

<div ng-controller="StoreController as store">
  <ul ng-repeat="product in store.products" class="list-group">
    <li class="list-group-item">
        <h3> {{product.name}} <em class="pull-right">{{product.price | currency }}</em></h3>
        <div class="gallery">
          <div ng-repeat="img in product.images | addIds ">
            {{img.id}}
            <img ng-src="{{img.full}}"/>
          </div>
        </div>
        <p>  {{product.description}}</p>
        <button ng-show="product.canPurchase">Add to Cart</button>
    </li>
  </ul>
</div>

And for the sake of completeness, here goes app.js.coffee

app = angular.module 'store', ['storeFilters']

app.controller 'StoreController',
  class StoreController
    constructor: ->
      @products = gems

gems = []

Upvotes: 1

Views: 301

Answers (3)

Dylan Piercey
Dylan Piercey

Reputation: 46

I'm not sure what your current id's look like (either starting from a random number or from 0 to the length of the images), but you could just grab the index within the for loop and do this:

for product in @products when product.images?
  img.id = current_id + i for img, i in product.images

or if its just the index:

for product in @products when product.images?
  img.id = i for img, i in product.images

or to be cool:

img.id = i for img, i in product.images for product in @products when product.images?

Upvotes: 0

max taldykin
max taldykin

Reputation: 12908

You can use when condition in a loop:

for product in @products when product.images?
  for img in product.images
    img.id = current_id
    current_id += 1

Upvotes: 2

AlexandruB
AlexandruB

Reputation: 688

You need to check if product.images is not null like you do now for the loop, otherwise you will have an error. The example here shows what I am talking about.

Cheers!

Upvotes: 0

Related Questions