-
Notifications
You must be signed in to change notification settings - Fork 123
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
Selector API improvements #257
Conversation
Codecov Report
@@ Coverage Diff @@
## master #257 +/- ##
==========================================
+ Coverage 99.77% 99.81% +0.03%
==========================================
Files 13 14 +1
Lines 909 1074 +165
Branches 155 209 +54
==========================================
+ Hits 907 1072 +165
Misses 2 2
Continue to review full report at Codecov.
|
Is there a migration guide for this? |
Not yet, but it's mostly a backwards-compatible change. All you need to do is specify a Converting complex selectors should turn out to be quite intuitive. I might write this up a bit in the future, but this will take a while. |
One simple example from our tests: -const movieRating = createSelector(
- orm,
- state => state.orm,
- (state, id) => id,
- ({ Movie }, id) => Movie.idExists(id) ? Movie.withId(id).rating : null,
-);
+const movieRating = createSelector(orm.Movie.rating);
-const publisherAverageRating = createSelector(
- orm,
- state => state.orm,
- state => state,
- (state, id) => id,
- ({ Publisher }, state, id) => {
- if (!Publisher.idExists(id)) return null;
- const ratings = Publisher.withId(id).movies.toRefArray()
- .map(movie => movieRating(state, movie.id));
- return ratings && (ratings.length ? avg(ratings) : 'no movies');
- },
-);
+const publisherAverageRating = createSelector(
+ orm.Publisher.movies.map(movieRating),
+ ratings => ratings && (ratings.length ? avg(ratings) : 'no movies'),
+);
publisherAverageRating(store.getState(), 1);
+// now works with arrays as the 2nd argument (for publishers with ID 1, 2, 3 or 4)
+publisherAverageRating(store.getState(), [1, 2, 3, 4]);
+// now also works with nothing as the 2nd argument (for all publishers)
+publisherAverageRating(store.getState()); Note that in the above example there would have been no need to have a separate -const movieRating = createSelector(
- orm,
- state => state.orm,
- (state, id) => id,
- ({ Movie }, id) => {
- if (!Movie.idExists(id)) return null;
- const ratings = Movie.withId(id).userRatings.toRefArray();
- return ratings && (ratings.length ? avg(ratings) : null);
- },
-);
+const movieRating = createSelector(
+ orm.Movie.userRatings,
+ ratings => ratings.length ? avg(ratings) : null,
+); |
Implements #251 and contains checks to avoid #256.
ORM
reference.stateSelector
option duringORM
construction.publishers(state)
:publishers(state, 1)
:null
orpublishers(state, [1, 2])
:publisherMovies(state)
:publisherMovies(state, 1)
:[]
orpublisherMovieRatings(state)
:publisherMovieRatings(state, 1)
: same as abovepublisherMovieRatings(state, [1, 2])
: same as aboveAllow for all types of relationship fields (only collectionsoneToOne
,fk
,many
)orm.<Model>.<field>.map(<selector>)
, e.g:ORM#createReducer
andORM#createSelector
to prevent reselect from being bundled unnecessarily.orm.<subtree>
:orm.<Model>
orm.<Model>.<field>
orm.<Model>.<field1>.….<fieldN>
recursively1
to fieldn - 1
(potentially also fieldn
) being single referenced relationship fields,for instance
orm.Movie.director.userAccount.paymentAccount.payments
same as passingorm.<Model>.map(<selector>)
selector
orm.<Model>.<field1>.….<fieldN>.map(<selector>)
To do in the future:
Model.filter
, as inPublisher.filter({ id: [1, 2] })
.