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

Add RecordArray#filterBy which contains a live, filtered subset #3263

Merged
merged 1 commit into from
Aug 3, 2015
Merged

Add RecordArray#filterBy which contains a live, filtered subset #3263

merged 1 commit into from
Aug 3, 2015

Conversation

pangratz
Copy link
Member

@pangratz pangratz commented Jun 8, 2015

This method takes the parameters key and an optional value and
returns an updating list of records of the RecordArray, which'
property value of key matches value.


This addresses #3171

// `internalRecords`, so we can use the `Ember.computed.filterBy` macro,
// which listens to changes of this property
internalRecords: Ember.computed.mapBy('content', 'record'),
arrangedContent: Ember.computed.filterBy('internalRecords', key, value)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very unsure about this implementation, since record on the InternalModel should be accessed via getRecord() I guess...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ember.computed.filterBy('internalRecords') should be filterBy content

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but then store.all('person').filterBy('name', xxx) is always an empty array. So I guess observing InternalModel's and properties on them doesn't work as expected yet ...

@pangratz
Copy link
Member Author

pangratz commented Jun 9, 2015

@igorT I am not sure about naming the method filterBy, since the RecordArray#filterBy method (inherited by ArrayProxy) is hereby overwritten with a different implementation: an auto-updating filtered subset. Maybe it should be renamed into something like updatingFilterBy, liveFilterBy or so ...

@cibernox
Copy link
Contributor

cibernox commented Jun 9, 2015

IMO the name it's ok as it is.
Seems reasoable to me that the filterBy method of a live collection returns another live collection.

@fivetanley
Copy link
Member

Can we move the ArrayProxy class definition out of the function? It doesn't need to be in its own file (might be nice), but it seems like it could get expensive to create a new class every time a filter is created.

@pangratz
Copy link
Member Author

pangratz commented Jun 9, 2015

@fivetanley done

This method takes the parameters `key` and an optional `value` and
returns an updating list of records of the `RecordArray`, which'
property value of `key` matches `value`.
@bmac
Copy link
Member

bmac commented Jul 24, 2015

Looks good. Should this also be implemented on a ManyArray?

@bmac
Copy link
Member

bmac commented Aug 3, 2015

Thanks @pangratz

bmac added a commit that referenced this pull request Aug 3, 2015
Add `RecordArray#filterBy` which contains a live, filtered subset
@bmac bmac merged commit 4ed50e5 into emberjs:master Aug 3, 2015
bmac added a commit to bmac/data that referenced this pull request Aug 3, 2015
bmac added a commit that referenced this pull request Aug 3, 2015
Fix failing tests from merging PR #3263
bmac added a commit that referenced this pull request Aug 4, 2015
(cherry picked from commit 848fb37)
@bendemboski
Copy link

This change seems problematic to me.

First of all, it's a breaking change. Previously a call to filterBy on a RecordArray would call ArrayProxy's filterBy method which returns a native array. So, the following code would behave as expected and would call doSomething:

let recordArray = getRecordArraySomehow(),
    newRecords = recordArray.filterBy('isNew');
if (newRecords.length > 0) {
    doSomething();
}

After this update, the same code will not run doSomething because newRecords is no longer a native array, so length is a computed property and newRecords.length is not an integer, so newRecords.length > 0 will always be false.

Now before updating to Ember Data 1.13.8 I have to audit all of my usages of RecordArrays to make sure I don't treat the return value like a native array anywhere :(

Secondly, it seems wrong to override filterBy but not override filter. This means that recordArray.filterBy('isNew') will return an ArrayProxy but recordArray.filter(function (record) { return record.get('isNew'); }) will return a native array. Same inconsistency applies to reject and to rejectBy.

Perhaps the decision to name this method filterBy could be re-visited? Or some kind of warning could be added to the release notes (I know it's already released...)?

@bmac
Copy link
Member

bmac commented Aug 10, 2015

Hi @bendemboski. Thanks for bringing up this issue. We talked about this issue in a recent team meeting and it sounds like this is a regression that we want to fix. The current fixing is we will back out the filterBy changes and replace it with a new name or a more limited API.

@cibernox
Copy link
Contributor

I've also faced the same.
I was chaining this.get('manyRelation').filterBy('isNew', false).sort(compareFn) and that broke too, since there is no sort function in this new kind of liveArray.

I'm explicitly converting the relation to an array before filter/sort this.get('manyRelation').toArray().filt....

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

Successfully merging this pull request may close these issues.

7 participants