Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JHipster: Filtering entities with criteria - intended Angular client-side approach

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:

  • Have I missed the intended way of doing this with the current JHipster version?
  • What is the intended use of req.query in the current implementation of request-utils.ts?
  • Is this area expected to change in upcoming versions? For example, might front-end search fields be automatically generated in the way in which ElasticSearch-enabled apps do (but for each entity attribute)?

Many thanks.

like image 399
ImperfectClone Avatar asked Nov 05 '17 01:11

ImperfectClone


1 Answers

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.

like image 166
Renszarv Avatar answered Nov 04 '22 02:11

Renszarv