Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code anomoly in src/lib/collection.html #3901

Closed
akc42 opened this issue Sep 6, 2016 · 5 comments
Closed

Code anomoly in src/lib/collection.html #3901

akc42 opened this issue Sep 6, 2016 · 5 comments
Labels

Comments

@akc42
Copy link

akc42 commented Sep 6, 2016

I don't really understand the collection code, but I was just single stepping through it trying to uncover a problem with iron-list when I hit a piece of code that just looks as though it might be a bug. I don't know, but I thought I would report it here so someone who knows what the code is doing can look at it and see if that is the case.

The code in point is lines 99-102 of src/lib/collection.html which goes like this

var old = this.store[key];
if (old) {
this._removeFromMap(old);
}

The old value that I was replacing in the store was a numeric zero (ie 0) with the value 5. I couldn't see the logic of why the value of 0 as opposed to 5 should be treated differently. I suspect that test for the truthy ness of old should really be something like if (old !== undefined) or something.

(For context - I have an iron list of records retrieved from a database. Each record is an array entry and each field in the record is an array entry. A particular field had the value 0 and I was trying to replace it with the value 5. I was also changing other values in the field array which were strings and was trying to find out why they don't change on screen although they do change in the model)

Anyway - make of it what you will.

@jfrazzano
Copy link

Hey Alan,

I can’t say for certain this is the answer to your question, but I believe that the data binding uses a map, that holds a collection, which uses unique keys. As for your question about the primitives 0 and 5 not being treated differently by the binding, again, I believe the issue is referenced here:

https://www.polymer-project.org/1.0/docs/devguide/model-data#array-mutation https://www.polymer-project.org/1.0/docs/devguide/model-data#array-mutation

It’s the developers guide and it says the following:

Work with arrays

Use Polymer's array mutation methods to make observable changes https://www.polymer-project.org/1.0/docs/devguide/data-system#observable-changes to arrays.

If you manipulate an array using the native methods (like Array.prototype.push), you can notify Polymer after the fact.

Note that Polymer's array handling has the following constraints:

Array items must be unique. The data system uses object identity to compare array items, so array items must be unique.

Primitive array items are not supported. This is because primitives (like number, string and boolean values) with the same value are represented by the same object. Consider an array of numbers:

this.numbers = [1, 1, 2];
The data system can't handle changes to this array property, because the first two items aren't unique.

You can work around these constraints by wrapping primitives in objects to ensure uniqueness:

this.numbers = [{ value: 1}, {value: 1}, {value: 3}];
Mutate an array

I hope I was helpful. I am more than willing to answer any questions I can help on. Been building in polymer for about 9 months and I think I might have “had” (caused) every possible “issue” one could inflict upon himself. Iron list was particularly challenging, then i built one, and saw how it worked. And where the unbelievable issues with dom selection start to get really awful.

Again hope that helps.

Jason

On Sep 6, 2016, at 2:27 AM, Alan Chandler notifications@github.com wrote:

I don't really understand the collection code, but I was just single stepping through it trying to uncover a problem with iron-list when I hit a piece of code that just looks as though it might be a bug. I don't know, but I thought I would report it here so someone who knows what the code is doing can look at it and see if that is the case.

The code in point is lines 99-102 of src/lib/collection.html which goes like this

var old = this.store[key];
if (old) {
this._removeFromMap(old);
}
The old value that I was replacing in the store was a numeric zero (ie 0) with the value 5. I couldn't see the logic of why the value of 0 as opposed to 5 should be treated differently. I suspect that test for the truthy ness of old should really be something like if (old !== undefined) or something.

(For context - I have an iron list of records retrieved from a database. Each record is an array entry and each field in the record is an array entry. A particular field had the value 0 and I was trying to replace it with the value 5. I was also changing other values in the field array which were strings and was trying to find out why they don't change on screen although they do change in the model)

Anyway - make of it what you will.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub #3901, or mute the thread https://github.com/notifications/unsubscribe-auth/AHxnvkZ4WseVpe2yo4sisqGGRP7B6aoBks5qnQflgaJpZM4J1gHb.

@akc42
Copy link
Author

akc42 commented Sep 6, 2016

@jfrazzano thanks for your comment. There are a couple of things to mention.

Firstly it disturbs me greatly that array members have to be unique. I have looked through (again) the references that you cite and can find no mention of this horrible limitation. Can you give a more specific reference for it. I can understand why it might be for arrays where the order might change, but I can't find it in the docs, and I hope it isn't a limitation if you aren't worried about immutable references - just hope there isn't a memory leak.

I have a number of cases where I am using dom-repeat templates to output the fields from a database query, where I don't know ahead of time how many fields are going to be returned. The server returns multiple rows as an Array of rows, BUT ALSO returns all the values of fields in the row as an Array of fields. I am using iron-list for the array of rows, but dom-repeat as an array of fields. So far this all works very well. Figures crossed there is no memory leak

I do have one case (which is the case I am investigating for not working) based in one of these database queries, where I want to allow the user to update the data in situ . This data was three fields with a text value, a date and an ID for the text field represented by the number. What I was tracking through the code above was changing the the ID from a 0 to a 5. In this I had used a previous selection event to retrieve the 'model' of an <iron-list> and used the model.set('row.12',5) function to update the value. This appears to have worked (the model is definitely updated as I can return to it later and find the correct updated data there), but the iron-list is not updating what is on the display.

As I hadn't quite understood what was happening, I had put a breakpoint on the _itemsChanged function in iron-list and was single stepping when I came to this piece of code. As it happens, iron-list isn't doing anything in this function because the old and new values of the model are the same at this point, but it was using the '#' version of the keys to look at its version of the model. I still have to go back and spend more time on why the original model update is not updating the display.

@timeu
Copy link

timeu commented Sep 6, 2016

@akc42 : here are some references:

#1385
#1913
#3062

AFAIK the recommended approach is to wrap primitives (Strings, Numbers, etc) in objects and add them to the array.

@arthurevans
Copy link

@TimvdLippe
Copy link
Contributor

Closing this issue as the file no longer exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants