I've recently started using JHipster - thanks to the maintainers for this fantastic project!
In the current version of JHipster (4.10.2 at the time of writing), entities can have filtering enabled via the entity sub-generator, or by including filter EntityName
and service EntityName with serviceClass
to the project's JDL file. This produces a Spring project in which the getAllEntities()
method in the EntityNameResource
class takes a Criteria
argument constructed from the URL GET
params.
This works out-of-the box with the Swagger UI generated for the endpoint, and the queries issued by this UI demonstrate that the back-end expects each criterion to be in the form of a GET
parameter key-value pair; this is consistent with the 4.10.2 Filtering docs.
However, I wonderd whether there is an intended approach to using this from a front-end Angular project that I have missed, beyond making appropriate modifications oneself to construct a conforming URL.
The front-end services use the static function createRequestOption(req)
(exported from app/shared/model/request-util.ts
) to populate the GET
parameters for paging and sorting. This function also expects that the passed-in req
object may have a query
attribute; initially, I thought that populating this parameter was the intended way to use the back-end filtration.
However, the implementation of createRequestOption(req)
currently places the value of req.query
into a GET
parameter called query
; i.e this does not produce the query format expected by the back-end, which expects a separate GET
parameter per criterion.
The solution which I have used is to modify createRequestOption(req)
to expect an array of key-value pair objects instead of req.query
(I've called it req.criteria
), and add these to the URLSearchParams
's array (it has to be the array, not the map, since there may be multiple parameters with the same key, e.g. name.in=Megatron&name.in=Optimus
).
So I've changed:
params.set('query', req.query);
to:
if (req.criteria && req.criteria.length > 0) {
req.criteria.forEach((criterion) => {
params.append(criterion.key, criterion.value);
});
}
...with component code populating the array along the lines of the following:
let criteria = [
{key: 'name.equals', value: 'Optimus'},
{key: 'power.equals', value: '10'}
];
this.entityService.query({
page: this.page - 1,
size: this.itemsPerPage,
sort: this.sort(),
criteria
});
I just created an example of this working in practice with some form fields filtering a test single-entity monolithic app (currently equals queries only) with this approach in GitLab here.
So, my questions are:
req.query
in the current implementation of request-utils.ts
?Many thanks.
I've done very similar thing in my projects too, in my solution the criteria is used like this:
let criteria = {
'name.equals' : 'Optimus',
'power.equals' : '10'
};
Currently, I work on an 'auto-complete' field, which will use the criteria, and has the necessary extension to the request-util.ts. Here: https://github.com/jhipster/generator-jhipster/pull/6618
And yes, I think, that parameters of that 'query' method is bit confusing, it need to be be simplified a bit.
Maybe, we can generate a client side version of the 'EntityCriteria.java', as 'entity-criteria.ts', but I'm not sure. There is a constant push against new features, and less code, which I could understand.