# How to make an a responsive table grid with alphabetical ordered columns

**URL:** <https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995>\
**Category:** Uncategorized\
**Created:** [August 25, 2019, 7:40pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995 "2019-08-25T19:40:52Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 25, 2019, 7:40pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/1 "2019-08-25T19:40:52Z")

</div>

After much Googling throughout the day and night this weekend I found a way to create an alphabetic table grid and insert it into the DOM. [I was thrilled to get it working with this Twiddle](https://ember-twiddle.com/4dfad2612b5d8b8ede138b92f60ebf84?openFiles=templates.components.each-table.hbs%2C), but I’m running into trouble getting it to work in my app.

Does anyone know how to `var array = [dynamic array]` in an Ember Helper?

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [August 26, 2019, 2:05am UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/2 "2019-08-26T02:05:34Z")

</div>

The path you’re headed down is going to be hard to get right. For example

- there’s a bug that causes the previous render to not be removed when running again (when the window resizes, for example).
- it’s leaking a global event listener
- the helper throws an exception when its module is evaluated (it’s trying to return a non-existent function)
- it works by accident of timing and wouldn’t work in a real app if you navigated away from it and came back

You will fight more bugs if you try to efficiently re-render when the array changes. Many of the problems you’re trying to solve are ones that Glimmer is already built to solve for you.

[Here I rewrote the Twiddle to use an alternative implementation](https://ember-twiddle.com/c7cd6f3f7b8dd8a8c6ed4072fc4e4b9f?openFiles=components.alpha-grid.js%2C). Future readers are warned that the twiddle is using a somewhat old Ember version, and below I’m translating into the more current style. The highlights are:

```nohighlight
{{#each rows as |row|}}
  <div style="display: flex">
    {{#each row as |item|}}
      <div style="min-width: 100px">{{item}}</div>
    {{/each}}
  </div>
{{/each}}

```

```nohighlight
import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
  rows: computed('names.[]', function() {
    let names = this.names;
    let columns = Math.floor(window.innerWidth / 100);
    let itemsPerColumn = Math.ceil(names.length / columns);
    
    let rows = [];
    for (let rowNumber = 0; rowNumber < itemsPerColumn; rowNumber++) {
      let row = [];
      for (let i = rowNumber; i < names.length; i+= itemsPerColumn) {
        row.push(names[i]);
      }
      rows.push(row);
    }
    return rows;
  }),
  handleResize() {
    this.notifyPropertyChange('rows');
  },
  didInsertElement() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener('resize', this.handleResize);
  },
  willDestroyElement() {
    window.removeEventListener('resize', this.handleResize);
  }
});

```

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 26, 2019, 4:08am UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/3 "2019-08-26T04:08:58Z")

</div>

Outstanding and infinitely more elegant than my hacky solution for alphabetical table grids in Ember (I always try to SEO-up my comments here for the future guy like me trying to figure all this out 😊).

Interestingly I just discovered the resizing bug and was afraid what it was going to do to my week. Greatly appreciate you taking the time.

Would I be able to this.store.getAll on the component [similar to the push answer here](https://discuss.emberjs.com/t/push-product-into-an-array-model-controller/13953/4) to get the dynamic array working?

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 26, 2019, 4:10am UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/4 "2019-08-26T04:10:47Z")

</div>

Oops. Overlooked the computed property for this.name. Wow, can’t wait to plug this in in the morning. Thank you!

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 26, 2019, 12:59pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/5 "2019-08-26T12:59:04Z")

</div>

Here come the errors.

Out of the gate it throws:

`Uncaught TypeError: Cannot read property 'length' of undefined`.

So I switch things up and add `this.get.findAll`.

```auto
import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
  rows: computed('terms.[]', function() {
    let params = this.get.findAll('term', { letter: params.letter });
    let columns = Math.floor(window.innerWidth / 100);
    let itemsPerColumn = Math.ceil(params.length / columns);

    let rows = [];
    for (let rowNumber = 0; rowNumber < itemsPerColumn; rowNumber++) {
      let row = [];
      for (let i = rowNumber; i < params.length; i+= itemsPerColumn) {
        row.push(params[i]);
      }
      rows.push(row);
    }
    return rows;
  }),
  handleResize() {
    this.notifyPropertyChange('rows');
  },
  didInsertElement() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener('resize', this.handleResize);
  },
  willDestroyElement() {
    window.removeEventListener('resize', this.handleResize);
  }
});

```

It says:

```auto
`Uncaught ReferenceError: Cannot access 'params' before initialization`

```

Being fairly certain this has something to do with the component lifecycle, I tinker around with various forms of init, which all send me back to:

`Uncaught TypeError: Cannot read property 'length' of undefined`.

Where have I gone wrong?

_**[(here’s the latest repo in case it helps)](https://github.com/jameshahn2/glossary-app)**_

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [August 26, 2019, 1:18pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/6 "2019-08-26T13:18:51Z")

</div>

You’re using `params.letter` before `let params`.

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 26, 2019, 1:33pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/7 "2019-08-26T13:33:29Z")

</div>

Apologies if I seem a little thick… I just finally figured out what all those `j` and `i` things meant this weekend. The joys of being self-taught. 🧐

I knew this wouldn’t work, but not sure how to separate the two.

```auto
export default Component.extend({
  rows: computed('terms.[]', function() {
    let params = this.terms
    this.get.findAll('term', { letter: params.letter });
    let columns = Math.floor(window.innerWidth / 100);
    let itemsPerColumn = Math.ceil(params.length / columns);

    let rows = [];
    for (let rowNumber = 0; rowNumber < itemsPerColumn; rowNumber++) {
      let row = [];
      for (let i = rowNumber; i < params.length; i+= itemsPerColumn) {
        row.push(params[i]);
      }
      rows.push(row);
    }
    return rows;
  }),
  handleResize() {
    this.notifyPropertyChange('rows');
  },
  didInsertElement() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener('resize', this.handleResize);
  },
  willDestroyElement() {
    window.removeEventListener('resize', this.handleResize);
  }
});

```

And.

```auto
Uncaught TypeError: Cannot read property 'letter' of undefined

```

Of course.

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 26, 2019, 8:32pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/8 "2019-08-26T20:32:15Z")

</div>

Was able to get the store working with:

```auto
// alpha-grid/component.js

import Component from '@ember/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';

export default Component.extend({
  router: service(),

  rows: computed('terms.[]', function() {
    let params = this.router.currentRoute.params
    let terms = this.terms;
    console.log(this.terms)
    let columns = Math.floor(window.innerWidth / 100);
    let itemsPerColumn = Math.ceil(terms.length / columns);

    let rows = [];
    for (let rowNumber = 0; rowNumber < itemsPerColumn; rowNumber++) {
      let row = [];
      for (let i = rowNumber; i < terms.length; i+= itemsPerColumn) {
        row.push(terms[i]);
      }
      rows.push(row);
    }
    return rows;
  }),
  handleResize() {
    this.notifyPropertyChange('rows');
  },
  didInsertElement() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener('resize', this.handleResize);
  },
  willDestroyElement() {
    window.removeEventListener('resize', this.handleResize);
  }
});

```

And:

```auto
// term/letter/template.hbs

{{alpha-grid terms=model}}

```

However, while I can see the terms in console, I can’t see them on the page. Feels like the last step is a change here, but I can’t find the right combination.

```auto
{{!-- alpha-grid/template.hbs }}

{{#each rows as |row|}}
	<div style="display: flex">
		{{#each row as |item|}}
			<div style="min-width: 100px">{{item}}</div>
		{{/each}}
	</div>
{{/each}}

```

Am I wrong?

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [August 26, 2019, 11:29pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/9 "2019-08-26T23:29:18Z")

</div>

_ **MASSIVE** _ shout-out to @jenweber for helping me debug this throughout the day!

The problem was hiding in plain site at:

```auto
row.push(terms[i]);

```

As she explained , arrays of models have their own accessors. Therefore, we swapped that out for:

```auto
row.push(terms.objectAt(i));

```

And just like that, my 1-year old problem was _ **SOLVED!** _

 ![responsive-grids3](https://us1.discourse-cdn.com/flex019/uploads/emberjs_public/original/3X/a/6/a6418793e77a54811b571d2a2d582c38eb90045e.gif)

So the final code looked like:

```auto
// alpha-grid/component.js

import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({

  rows: computed('terms.[]', function() {
    let terms = this.terms;
    let columns = Math.floor(window.innerWidth / 100);
    let itemsPerColumn = Math.ceil(terms.length / columns);
    let rows = [];
    for (let rowNumber = 0; rowNumber < itemsPerColumn; rowNumber++) {
      let row = [];
      for (let i = rowNumber; i < terms.length; i+= itemsPerColumn) {
        row.push(terms.objectAt(i));
      }
      rows.push(row);
    }
    return rows;
  }),
  handleResize() {
    this.notifyPropertyChange('rows');
  },
  didInsertElement() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener('resize', this.handleResize);
  },
  willDestroyElement() {
    window.removeEventListener('resize', this.handleResize);
  }
});

```

```auto
{{!-- alpha-grid/template.hbs (includes TailwindCSS) }}

<div class="flex flex-wrap">
	{{#each rows as |row|}}
		<div class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/4 xxl:w-1/4 txl:w-1/4 txl:w-1/4 fxl:w-1/4">
			{{#each row as |item|}}
				<div>{{item.term}}</div>
			{{/each}}
		</div>
	{{/each}}
</div>

```

```auto
{{!-- term/letter }}

{{alpha-grid terms=model}}

{{outlet}}

```

Thank you all!

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 3, 2019, 2:03pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/10 "2019-09-03T14:03:50Z")

</div>

Hi @ef4 , thought I solved this problem with TailwindCSS, but turns out I wasn’t looking close enough and the terms were no longer alphabetized. So I rolled it back to flex/min-width and this is the result.

 ![clientWidth](https://us1.discourse-cdn.com/flex019/uploads/emberjs_public/original/3X/5/0/50545b0fa3b3bae95ea5e94264cf38402437f542.gif)

After wrestling with it through the long weekend, I concluded this comes from `window.innerWidth` (or `$(window).width()` in the Twiddle, along with the subsequent `window.addEventListener` and `window.addEventListener`.

Would you recommend using [clientWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) instead, and, if so, how? Found [another answer of yours](https://discuss.emberjs.com/t/how-to-use-functions-events-and-html-dom-in-ember/16672/2) on the subject, but don’t know if the same workflow applies here. Also found [ember-in-viewport](https://github.com/dockyard/ember-in-viewport#classes) and it seems like it could provide a way to make this work.

Is there a good way to bind the table/grid to the width of an element instead of the window?

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [September 3, 2019, 2:28pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/11 "2019-09-03T14:28:37Z")

</div>

> [@jameshahn2](#):
>
> Is there a good way to bind the table/grid to the width of an element instead of the window?

You can definitely _measure_ the width of any element, but you can’t easily get an event telling you _when_ a particular element changed size. That said, it’s probably enough to continue relying on window resize events (since the only thing likely to change the size of your element is a change in the size of the window).

So you can keep `window.addEventListener('resize', ...)` but replace `window.innerWidth` with `this.element.getBoundingClientRect().width`.

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 3, 2019, 2:44pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/12 "2019-09-03T14:44:26Z")

</div>

Much better, but still a little out of bounds. Is there a way to set some kind of `rowMax` to keep it under 5 columns?

 ![53](https://us1.discourse-cdn.com/flex019/uploads/emberjs_public/original/3X/c/f/cfce43fd44b9eef3f824f4744442d8869bb9fe4f.png)

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 3, 2019, 3:44pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/13 "2019-09-03T15:44:29Z")

</div>

Don’t know if this will work once we have thousands of words on the page, but for now was able to make it work with:

`let columns = Math.floor((this.element.getBoundingClientRect().width / 100) / 1.5 );`

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [September 3, 2019, 4:07pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/14 "2019-09-03T16:07:48Z")

</div>

In my original example the columns were fixed at 100px wide, which is why there’s a divide-by-100 in that code. If you pick a different size for the columns, change it to match. There shouldn’t be a need for a fudge factor like the extra 1.5.

If things still aren’t fitting correctly, double-check that the element you’re measuring has the geometry you expect (by giving it a border or something visible).

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 3, 2019, 4:41pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/15 "2019-09-03T16:41:40Z")

</div>

Ahhhh, ok. I see what you did there.

Yes, the element was set wrong and being measured wrong. Fixed it, then stretched the min-width to 175px, set a max-width at 175px to force breaks in the long terms, and added 8px of padding.

Works!

 ![06](https://us1.discourse-cdn.com/flex019/uploads/emberjs_public/original/3X/a/0/a0641ff0c724cbf34de2f469738c2277448ed5f3.png)

Thank you!!

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 3, 2019, 8:54pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/16 "2019-09-03T20:54:00Z")

</div>

Sorry to bother you so much today, @ef4. One more question on this.

I’ve got to break the terms up separately based on first letter. I tried using `ember-composable-helpers`, but unless I’m doing it wrong using `group-by` forces the terms into horizontal alphabetization, instead of the desired vertical result.

Went with `ember-truth-helpers` to do an “if equals” conditional comparison like so:

```auto
<h3>M</h3>
{{#each rows as |row|}}
	<div class="alpha-grid">
		{{#each row as |item|}}
			{{#if (eq item.letter "m")}}
				<div class="alpha-item"><a class="text-blue-light text-sm no-underline" href="{{href-to "terms.letter.term_id" item.letter item.id}}">{{item.term}}</a></div>
			{{/if}}
		{{/each}}
	</div>
{{/each}}

```

It solves the left-to-right alphabetization problem while creating another issue. Here’s a screenshot showing the situation.

 ![14](https://us1.discourse-cdn.com/flex019/uploads/emberjs_public/original/3X/1/1/119232cb04b07f7bd0e5b18a074386d4549dc13d.png)

The first 3 terms do not `eq item.letter "m"` and aren’t shown. However, they are replaced by the last 3 rows moving left and pushing the true first “M” term down… which throws everything off.

Is there a way to prevent this behavior or `group-by` without breaking the flex?

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [September 4, 2019, 12:14am UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/17 "2019-09-04T00:14:47Z")

</div>

Assuming you have an `{{alpha-grid}}` component that works the way you want, don’t mess with it. Instead, call it multiple times, with different batches of words for each letter. You can do the grouping by letter in Javascript in a new, outer component that calls alpha-grid.

If you actually want the empty letters to appear (as in your screenshot), you’ll need to iterate through the whole alphabet.

```auto
// this will return a list structured like:
//
// [ 
// {letter: "a", names: [] }, 
// { letter: "b", names: ["banana", "byte"] },
// ... and so on
// ]
letterGroups: computed(`names.[]`, function() {
  let groups = [];

  // "a" is ascii code 97. "z" is 122.
  for (let letterIndex = 97; letterIndex < 123; letterIndex++) {
    let letter = String.fromCharCode(letterIndex);
    groups.push({
      letter,
      names: this.names.filter(name => name[0].toLowerCase() === letter))
    });
  }
  return groups;
})

```

Then in your template:

```nohighlight
{{#each letterGroups as |group|}}
  <h2>{{group.letter}}</h2>
  {{alpha-grid @names=group.names}}
{{/each}}

```

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 4, 2019, 2:39pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/18 "2019-09-04T14:39:34Z")

</div>

This is perfect. If I’m following you correctly, this is what I did.

1. Added a new component called `letterGroups` at `/app/pods/components/letterGroups/component.js`.
2. Replaced `name` with `term` throughout.
3. Added the template code (`{{#each letterGroups...}}`) to `/app/pods/disciplines/template.hbs`.

When I do this, it throws:

```auto
Parse error on line 5:
... {{alpha-grid @terms=group.terms}}{{/ea
-----------------------^
Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SEXPR', 'ID', 'OPEN_BLOCK_PARAMS', 'STRIN...

```

However, when I remove the `@` nothing happens. I’m running Ember 3.12, so should have all the latest decorators. Did I miss a step?

([repo with the latest push](https://github.com/jameshahn2/glossary-app))

---

<div class="post-metadata">

**Author:** ![ef4](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/ef4/32/13470_2.png) [@ef4](https://discuss.emberjs.com/u/ef4)\
**Post date:** [September 4, 2019, 4:02pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/19 "2019-09-04T16:02:02Z")

</div>

Oh, I’m mixing up my new and old syntax. You don’t need the `@` for curly invocation. So `{{alpha-grid terms=group.terms}}`.

---

<div class="post-metadata">

**Author:** ![jameshahn2](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jameshahn2/32/16087_2.png) [@jameshahn2](https://discuss.emberjs.com/u/jameshahn2)\
**Post date:** [September 4, 2019, 4:39pm UTC](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995/20 "2019-09-04T16:39:26Z")

</div>

Page was still blank after dropping `@`. Have another attribute in JSON called “group” so wondered if that was causing an issue.

 ![58](https://us1.discourse-cdn.com/flex019/uploads/emberjs_public/original/3X/6/f/6f223033e9a795e0da41a5c261fa4bbb75a8ee6e.png)

Changed everything to `letterBatches`, no luck there. The `alpha-grid` for this route is:

```auto
{{alpha-grid terms=model.terms}}

```

Have tried every combination of `model.batches.terms`, `batches.model.terms`, etc. I can think of and can’t find the right combination. Now have:

```auto
// /./letterBatches/component.js

import Component from '@ember/component';
import { computed } from "@ember/object";

export default Component.extend({
  // this will return a list structured like:
//
// [
// {letter: "a", terms: [] },
// { letter: "b", terms: ["banana", "byte"] },
// ... and so on
// ]
letterBatches: computed(`terms.[]`, function() {
  let batches = [];

  // "a" is ascii code 97. "z" is 122.
  for (let letterIndex = 97; letterIndex < 123; letterIndex++) {
    let letter = String.fromCharCode(letterIndex);
    batches.push({
      letter,
      terms: this.terms.filter(term => term[0].toLowerCase() === letter)
    });
  }
  return batches;
}),
});

```

With this in the template.

```auto
{{!-- /disciplines/template.hbs --}}

{{#each letterBatches as |batches|}}
  <h2>{{batches.letter}}</h2>
  {{alpha-grid terms=batches.terms}}
{{/each}}

```

[Next page](https://discuss.emberjs.com/t/how-to-make-an-a-responsive-table-grid-with-alphabetical-ordered-columns/16995.md?page=2)
