Is it possible to use `dom-repeat` to perform multiple `<firebase-query>` and aggregate the result in array? - polymer-1.0

Is it possible to use dom-repeat to perform multiple <firebase-query> and aggregate the results in an array using Observers? Such as:-
<template is="dom-repeat" items="[[queryUser]]">
<firebase-query id="queryDetail_[[index]]"
path="/users/[[item.$key]]/detail"
start-at="2017-01-01"
order-by-child="timestamp"
data="{{queryDetail.[[index]]}}">
</firebase-query>
</template>
observers: [
'_queryDetailChanged(queryDetail.*)',
]
The above code obviously doesn't work, it's just to demostrate the idea. Thanks!

Related

Angularjs: Ng-repeat and unique filter in array

I have a set of data like this
$scope.students = [
{ name:"John", courses:["Math", "Physics", "Chemistry"] },
{ name:"Paul", courses:["Economics", "Math", "Sociology"] }
]
I would like a way to filter using angular-filter so that I can get a list of all the subjects without repetition.
I've been trying to use unique filter, but I cannot get it to work since I try to iterate like
<ul ng-repeat="student in students">
<li ng-repeat="x in student.courses | unique:courses"></li>
{{x}}
</ul>
My desired output of the first ng-repeat would be an array like this:
["Math", "Physics", "Chemistry", "Economics", "Sociology"]
so I could iterate through it in the second one.
I have achieved this throught making a new scope with just the desired array, but then I cannot bind it properly, so I would like to achieve it through filtering. Thanks in advance.
I would really recommend you using the libraries Lodash or Underscore for this kind of problems. Learning to master these has helped me a lot!
Of course, you can create your own angular filter using one of them. The method you would like to use is union:
_.union(_.flatten(_($scope.students).pluck("courses")))
I use pluck to get out the courses arrays from the studens object, then I flatten the result (to get rid of the array that it comes nested in), and then i use union to get each subject only once.
If the requirement actually is to:
...get a list of all the subjects without repetition.
Then I would make a separate array for subjects:
$scope.courses = [];
// There are many ways to do skin this cat... (prograde does have a point!)
$scope.students.forEach(function(student) {
student.courses.forEach(function(course) {
if ( $scope.courses.indexOf(course) === -1 ) {
$scope.courses.push(course);
}
})
});
HTML
<ul>
<li ng-repeat="course in courses">
{{ course }}
</li>
</ul>
And if the students change I would recreate the courses-array.
But it sounds as if you are trying to do something else.
But it doesn't give the desired output.
It would help if you tell us what that desired output is!
http://plnkr.co/edit/bZNjIEFznvuyTU3zxAp1?p=preview

Polymer 1.0 itemForElement in nested dom-repeat

For example, I have a dom-repeat like this:
<template is="dom-repeat" id="rows" items="[[rows]]" as="row">
<tr class="result-tb-row" closed$=[[row.closed]]>
<td class="result-tb-data">
<ul class="violation-list">
<template id="rowItem" is="dom-repeat" items="[[row.items]]">
<li on-click="click">[[item]]</li>
</template>
<ul>
</td>
</tr>
</template>
If I want to know which row I am clicking on, I can write a something like this:
this.$.rows.itemForElement(event.target);
However, what if I want to get the exact item corresponding to li I clicked on. How do I do so? I obviously cannot do this.$.rowItem.itemForElement(event.target) because rowItem isn't unique.
Update
event.model.item seems to solve this particular problem. But if you have double nested dom-repeat or more and you want to get the middle layers, you're out of luck. Probably have to implement an iterator yourselves. double nested dom-repeat happens a lot in table. Table is already a nested dom-repeat; if you want a dom-repeat inside a table cell (and you will run into it), double nested dom-repeat happens.
It isn't hard to implement an iterator, just hope that the Polymer team supports more methods for nested dom-repeat because this is an awesome feature.
event.target holds a <li> reference.
When you do this.$.rowItem.itemForElement(event.target), the dom-repeat named rowItem is unique, and it will look what item belongs to that <li>.
But if you just want item data, you can use event.model.item, which holds a reference to the item data that belongs to the line you clicked.
This is a perfectly valid question, I'm facing the same situation. Anyone has a solution?
UPDATE
I found the ID in e.model.__data__. But this feels like a hack
Here it is. It took me a couple of apps to figure this out.
Polymer considers the inner ID to be a dynamically created ID. So using Polymer's automatic node finding for dynamic IDs, you can say:
this.$$('#rowItem').itemForElement(event.target)
As documented here:
https://www.polymer-project.org/1.0/docs/devguide/local-dom.html#node-finding

angularjs - track by in a for loop

I have a problem with the refresh button in my Angular application:
I have a json object with two arrays in it -> data = {array1: [], array2: []}
I want to loop both arrays and print the related values. To achieve that, I use the Angular ng-repeat directive like this:
ng-repeat="index in [] | index:getTotalNumberOfObjectsInArray1()"
...
<span ng-bind="data.array1[index]"></span>
<span ng-bind="data.array2[index]"></span>`
My Problem is, that on every click on the refresh-button these data will be recreated on the dom.
I learned the documentation about "track by" but i understand it only on objects (for example: ng-repeat="a in objects track by a.id")
How can I use this track by filter for my ng-repeat above, to prevent the recreation of my data?
You can use $index that is defined in a ng-repeat (cf.doc) but you have to have the two array with the same length.
Another solution could be to merge your arrays together and loop on it but I am not sure if it answer to your question.

Duplicate Key in Repeater, track by creates problems

I have an object I am trying to ng-repeat through.
The object is something like this:
ctrl.obj = {
"1": ["val1", "val2", ... ],
"3": ["val1", "val2", ... ],
...
"20": ["val1", "val2", ... ]
}
When I try:
<ul ng-repeat="item in ctrl.obj"></ul>
I get this angular error:
Error: ngRepeat:dupes
Duplicate Key in Repeater
The standard solution is to use track by $index. That does not work for my scenario though, because it now causes every integer between 0 and 20 to appear, even though I only have 1, 3, 7, 10, etc. I would ideally not like to reformat the object, as it is being loaded from outside the app ~ though this seems to be a recurring necessity with Angular.
What are my options for repeating through this object?
This object is a dictionary, where each property is a key, and each array is a value. To iterate through this properly, you would need two separate ng-repeat. something like the following:
<div ng-repeat="(key, value) in ctrl.obj">
{{key}} : {{value}}
<div ng-repeat="item in value">
{{item}}
</div>
</div>
There may be something else going on here, because I am unable to reproduce the error you are experiencing when using this syntax, though you state that the syntax causes an error in your situation. Can you post a sample of data which actually does cause this error?
http://plnkr.co/edit/LvvpxNqM6LuGVel4WQt9?p=preview
This plunker is using your original <ul>, and it is not producing any of the errors you are describing. It seems as though you haven't provided an accurate representation of the object you are trying to display here.
http://plnkr.co/edit/xgded2Ebrf0xKFuupOyr?p=preview
https://docs.angularjs.org/api/ng/directive/ngRepeat

ng-repeat over array of objects vs. object containing objects

In almost all the examples of ng-repeat I've seen, the data is structured like so:
$scope.dataCollected = [{name: bob, data: '10-12-12'}, {name:joe, data: '09-13-13'}];
However, the only way I can get ng-repeat to work is if I structure the data like this:
$scope.dataCollected = {bob: {name: bob, data: '10-12-12'}, joe: {name:joe, data: '09-13-13'}};
Structuring it as an array causes the ng-repeat to do absolutely nothing. It doesn't even give an error. Structuring it as an object containing objects works, but I'd like to use an array because I understand it's the only way to use a filter on ng-repeat.
I'm calling the ng-repeat like this:
<div class="list-row" ng-repeat="data in dataCollected">
<h3 class="name"> {{data.name}} </h3>
</div>
What am I missing?
Sorry guys, thank you for the help. The issue was that in an attempt to make my data easier to read, I had assigned names to the keys of the array using bracket notation as seen in the answer here: stackoverflow.com/questions/12244483/… ng-repeat does not like that at all. It seems the default keys are necessary.

Resources