I use the JSONAPI adapter/serializer. I would like to add queryParams to my url when fetching a hasMany relationships. Example:
When I do something like that gallery.get('illustrations', { sort: 'name' }), it triggers this (links related href works well):
GET /api/galleries/34/relationships/illustrations
But I would like to have:
GET /api/galleries/34/relationships/illustrations?sort=name
How can I add the sort queryParam to the url ?
As it stands now links have to come from the back end (or use a callback in the serializer). I have a pull-request which implements a buildUrlForHasMany function that could handle your scenario. It is a bit out of date but you may find it useful.
It has always irked me that I had to include a link or an array of ids to do a hasMany relationship when all the information is present on the parent to do the lookup.
Have you tried:
this.store.query('illustrations', { sort: 'name' });
in your router?
http://guides.emberjs.com/v2.0.0/models/finding-records/#toc_querying-for-multiple-records
@Finhas If I do what you describe, the url won't be /api/galleries/34/relationships/illustrations?sort=name but something like /api/illustrations?sort=name.
My request needs to consider the links related href value
@SeyZ Since you're requesting the relationship data in your controller, couldn't you sort the return in ember before it's displayed or have default sorting set on your server?
The server MAY apply default sorting rules to top-level data if request parameter sort is not specified.
Honestly, I was thinking your request on the router would return /api/galleries/34?includes=illustrations but I guess it depends on how many 'illustration' categories you need to fetch from the gallery.
I have created an addon for this that may be useful: https://github.com/mdehoog/ember-data-has-many-query. After configuring, simply:
gallery.query('illustrations', { sort: 'name' });
@mdehoog You rock! Thank you very much!
Please Ember Data's authors, implement it this way :D gallery.get('illustrations', { sort: 'name' })
This is so intuitive!
One year later, is it something you're working on? It would be awesome guys :)
I would like to add that the sort param use case is not the only one. Someone pointed out that the data could be sorted in the front-end after being fetched. But there are cases where a parameter could be needed for something that is not achievable in the front-end.
For instance, in json-api one can include or not some associated data in the response. It is common practice to parameterize the api endpoints to optionally request associated data alongside the originally requested resource.
# request all regions of country with id=27
# country27.get('regions')
/api/countries/27/regions
# request all regions of country with id=27, and include the regions' cities in the response
# country27.get('regions', { include: 'cities' })
/api/countries/27/regions?include=cities
Here are some examples of json-api responses with additional included data.
@mdehoog thanks. Exactly what I wanted
and I would like to add that paging would be another use-case.
(to me, like sorting, a pretty important one. actually surprises me that it's not supported yet.)
It is baffling indeed, given that this is such a common use case. I've dug into this in the emberjs slack community, and the official response is "sub-class the initializer", which is difficult, not generic enough, and misses the point of using ember data in the first place.
@gnapse can you expand a bit on the "sub-class the initializer" suggestion? No idea what that even means.
Doing the top-level store.query is great if you can do "Resource Linkage" (eg, return id's from the API), however doesn't really help us if we need to use relationship related links to load associated records.
I can understand worrying that post.get('comments', {page: 3, perPage: 10}) would mean that maybe subsequent calls to post.get('comments') represent a subset of the post's comments instead of _all_ of the post's comments... so I guess if I were designing the api, I'd put a query method on DS.HasManyReference instead. It wouldn't load() the relationship, but would let you do queries against that association.
EG
commentsRef = post.hasMany('comments');
commentsRef.query({page: 3}).then( (comments) => {
set(this, 'comments', comments);
});
post.get('comments') // would still trigger a request
We would happily accept a PR that passed includes / adapterOptions to load and reload on belongsTo and hasMany references and relationships.
@runspired next step would be an rfc or PR?
for reload and load, so long as it follows the existing API for passing includes and adapterOptions I do not believe we would require an RFC, as we consider this "feature fill" e.g. catching up a missing gap for an already accepted feature.
Any updates on this?
@tpetrone PR needed still
I believe that this can be closed.
@nathanhammond I infer that the PR right above your closing comment solves it. Does this mean that we can now fetch relationships exactly how the original issue request asked for?
// This will hit /api/galleries/34/relationships/illustrations?sort=name
// instead of just /api/galleries/34/relationships/illustrations
gallery.get('illustrations', { sort: 'name' })
Any chance to have this information in docs with full info about model relation types, routes etc, please ? ember-data 3.4.1 have that but I couldn't really head around that.
Bless Frank Treacy who explain how to solve that with your own code using adapter https://emberigniter.com/adding-query-parameters-hasmany-relationship/ Thank you Frank !
Most helpful comment
and I would like to add that paging would be another use-case.
(to me, like sorting, a pretty important one. actually surprises me that it's not supported yet.)