Ember: Selecting the object form array using index in #each loop - ember.js

Trying to use the index value in a loop in EmberJs
Consider the following scenario,
{{#each array1 as |element index|}}
<Component1 #prop={{element}} #prop2={{#array2[index]}} />
{{/each}}
I wish to send the object from the second array using the index value from first array. I cannot find any references to this. Any References i found use the first array alone and and didn't use the index in another variable.
Thanks in advance for your time and effort.

You can use get helper.
{{#each array1 as |element index|}}
<Component1 #prop={{element}} #prop2={{get #array2 index}} />
{{/each}}

Related

Ember - if lastItem in each

I am trying to show a piece of markup under the very last item in an each in ember -- I tried something like #last - but it came back with an error
<ul>
{{#each people as |person index|}}
<li>Hello, {{person.name}}! You're number {{index}} in line</li>
{{/each}}
</ul>
Ember's {{each}} template helper does not provide an easy way to do so.
As you might figured out, you could use {{unless index}} to conditionally render stuff on the first object. This is working since index starts at zero and 0 is considered to be falsely.
You could combine ember-truth-helpers and ember-math-helpers to achieve something comparable for last element. Both are well maintained ember addons that provide a full set of template helpers.
Ember-truth-helpers provides a eq helper that adds support for equal comparison in templates. Ember-math-helpers provides a sub helper to subtract a value from another in a template. Combining both of them we could build a condition that will be true only for the last element:
{{#each items as |item index|}}
<li>
{{item}}
{{#unless index}}(first){{/unless}}
{{#if (eq index (sub items.length 1))}}(last){{/if}}
</li>
{{/each}}
You find an ember twiddle demonstrating the approach here: https://ember-twiddle.com/6ea05a2e9c884bd772eefabc91173d08?openFiles=templates.application.hbs%2C
It's even simpler if the array is an Ember.NativeArray. NativeArray of ember provides a lastObject property, which points to the last item in the array. You could use that one for equal comparison directly as pointed out by #Gaurav in a comment: {{#if (eq item items.lastObject)}}(last){{/if}} But be aware that this may give wrong results if the array has duplicated elements.

Displaying a tag only for one element in a list. ember.js.(cloaked-collection, discourse)

I have a source code(discourse) than I need to work with with ember.js. I am trying handle only one "post" (the first) in a list using cloaked-collection.
//topics.hbs
{{#unless model.postStream.loadingFilter}}
{{cloaked-collection itemViewClass="post"
defaultHeight="200"
content=postsToRender
slackRatio="15"
loadingHTML=""
preservesContext="true"
uncloakDefault="true"
offsetFixedTop="header"
offsetFixedBottom="#reply-control"}}
{{/unless}}
//post.hbs
//some code here.
//Then I want to insert <div class="uniw"></div> only on the first post
The question is: for the list of itemViewClass="post", how can I check if I am in the first "post"? so that i can insert a piece if code.
You should be able to use firstObject to get first object of a collection. Something like this:
{{items.firstObject}}
Inside each block you can check index:
{{#each people as |person index|}}
{{#if (is-equal index 0)}}
{{person}}
{{/if}}
{{/each}}
Note that is-equal is non-standard helper. You can get it from ember-truth-helpers addon or write it yourself

How to get the LAST element in a list for Ember Acceptance Testing

When writing Acceptance tests, does anyone happen to know how one would select the LAST element in a list? I am testing the act of adding a new record to a list and would like to edit/delete the newly created record in my test.
I've tried to select the newly created record like this....
let newRecordLink = find('div.parent-list .list-group-item').last();
click(newRecordLink);
Which sorta works. It pulls the last element, but it busts out of my test and suddenly I'm on the actual page of the app I'm trying to test instead of remain within the test container.
Here is the relevant HBS code:
<div class="list-group parent-list">
{{#each model.owners as |item|}}
{{#link-to 'client.members.edit-owner' item.id class="list-group-item" id=item.id}}
<h4 class="list-group-item-heading">
{{item.firstName}} {{item.lastName}}
</h4>
{{/link-to}}
{{/each}}
</div>
You can use :last selector (https://api.jquery.com/last-selector/)
click('div.parent-list .list-group-item:last')
if it is an ember array u can use .get('lastObject')
I was struggling with this too, but I got it to work by using :last-of-type instead of :last

Binding values of all element content values in Ember

I have this an ArrayController with some elements in it. I display a property "content" of the elements in a list with Handlebars like this:
{{#each}}
<div id="editable" contenteditable="true">
<li>{{content}}</li>
</div>
{{/each}}
As noted in the template, I also make this editable (I have integrated the inline CKEditor) and I can edit these list items when I load the app.
The problem is that the changed data is not reflected back to the element object of the ArrayController, so that after I call save on the model, the "content" property is back to its original value.
If I modify the data by the ember textfield view, everything works fine, so changes are stored back into the element.
{{#each}}
<div id="editable" contenteditable="true">
<li>{{textarea value=content}}</li>
</div>
{{/each}}
Is there a way to tell handlebars that all element values should be two-way bound to the properties?
You need to bind value to the content.
This should solve your problem
<textarea {{bind-attr value=content}} />
// or
{{view Ember.TextArea value=content}}
The CKEditor must create a 'textarea' when you add 'contenteditable="true"'
This textarea is not bound to Ember controller.
So you can do :
1) get the value from CKeditor in the 'save' action.
or
2) Change CKeditor to make it Ember compatible.

EmberJS loop through array show key and value

Ok so I have a pretty simple array of objects that I retrieved with emberjs, now all I need it to do is have something along the lines of
{{#each array}}
{{value}}
{{/each}}
and have it so that the array is looped by each item, and each item then is looped by each value and I display all the values of that object, I am not sure how to get it to work.
I have used this helper here https://gist.github.com/strathmeyer/1371586 but it's no use, I have no idea where to start, it just seems like such a simple thing I don't understand why handlebars/ember doesn't support it, also does #key work at all with ember?
Thanks
Ember Handlebars doesn't support looping over objects.
To loop in an array you simply use
{{#each item in collection}}
{{item}}
{{/each}}
or
{{#each collection}}
{{this}}
{{/each}}