Al Grant
Al Grant

Reputation: 2354

Jhipster & Angular Filter

I have a Spring-Boot based Jhipster generated project with Angular. In the project is a Person entity. I want to know how to filter the html CRUD table on inputs on firstname field.

So if I enter in the input "bob" I would get all names containing "bob". Similar to this question. This filter should get the data from backend/server side, and not just what is displayed on the current page.

I am new to Angular so a verbose answer about what files need to be modified would be helpful.

Filtering has been enabled in jhipster. I want the input to trigger a filter server-side.

My table looks like:

enter image description here

I tried have added to my html:

<th>
  <form [formGroup]="userForm" (ngSubmit)="onEnter()">
    <input type="text" class="form-control" formControlName="firstname">
    <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
  </form>
</th>

In the person.component.ts I have created a method to capture the enter event:

  onEnter(): void {
  alert(JSON.stringify(this.userForm.value));
  this.personService.lastnameContains(this.userForm.value)
  }

And looking at person.service.ts which has some examples for update, delete find, I have this method:

  lastnameContains(lastname: string): Observable<EntityArrayResponseType> {
  return this.http
    .get<IPerson[]>(`${this.resourceUrl}?lastname.contains=${lastname}`, { observe: 'response' })
    .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
 }

The URL the request is sent to should be :

"http://localhost:8080/api/people?lastname.contains=searchstring"

UPDATE

There is a generated query method in the service:

query(req?: any): Observable<EntityArrayResponseType> {
    const options = createRequestOption(req);
    return this.http
        .get<IPerson[]>(this.resourceUrl, { params: options, observe: 'response' })
        .pipe(map((res: EntityArrayResponseType) => this.convert1DateArrayFromServer(res)));
 }

But it does not seem to have a way to direct the request to the correct URL.

enter image description here

The above picture shows the code is being called. But nothing is sent to the server at all, let alone at /api/person?lastname="somestring"

enter image description here

How does one implement this filtering. Jhispter docs are scant at best.

Upvotes: 1

Views: 4573

Answers (2)

Al Grant
Al Grant

Reputation: 2354

Start with enabling filtering in jhipster as per here.

Note that the EntityQueryService talked about at the bottom of the page under Implementation is a Spring service, and is YourEntityNameQueryService.

Front end stuff, beginging with the html, here is the code changes that makes a filter on lastname.contains work:

person.component.html

<th>
    <form [formGroup]="userForm" (ngSubmit)="onEnter()">
        <input type="text" class="form-control" formControlName="firstname">
        <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
    </form>
</th>

In particular I added the [formGroup]="userForm" which binds the html to the correct model (person). In the input tags formControlName="firstname" binds the input the firstname field of the entity, and the (ngSubmit)="onEnter" means the data is submitted by the enter key. The second input is a phantom button to capture the Enter event.

person.component.ts

import { IPerson } from 'app/shared/model/person.model';
import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants';
import { PersonService } from './person.service';
import { PersonDeleteDialogComponent } from './person-delete-dialog.component';
import { FormGroup, FormControl} from '@angular/forms';

@Component({
  selector: 'jhi-person',
  templateUrl: './person.component.html'
})
export class PersonComponent implements OnInit, OnDestroy {
   userForm = new FormGroup({
   firstname: new FormControl('test')
})

The changes that needed to be made to person.component.ts are:

  1. Added imports for FormGroup and FormControl;
  2. Added new FormGroup with a firstname FormControl;

Further down person.component.ts is a handler for the Enter key event:

  onEnter(): void {
      alert(JSON.stringify(this.userForm.value));
      this.personService
        .query({'lastname.contains': 'wood'})
        .subscribe(
          (res: HttpResponse<IPerson[]>) => this.onSuccess(res.body, res.headers, -1),
          () => this.onError()
        );;
  }

The enter event calls the personService.query method which was automatically generated when you enable jhispter filtering (see here). This query method will handle all the requests made to the API for you. When you call the query you must correctly construct the parameters - in this case lastname.contains=wood which is hard coded for testing.

IPerson represents the Interface to Person model.

Upvotes: 2

Sal Marquez
Sal Marquez

Reputation: 13

In your person.service.ts you should have a method query(req?: any). If you don't then you probably added filtering after the fact, and you didn't regenerate your gateway (if you're doing a micro service architecture).

This is the method you use for filtering. Just pass in your filter as an object (JSON). It's also the method you use for pagination, if you have that enabled. If you look at person.component.ts, you'll see an example of pagination.

Note: I'm on version 6.1.2, so your query method might be slightly different, but the concept is still the same.

Edit after your screenshots: You see how req="wood", it should equal an object representing the filter.

Upvotes: 0

Related Questions