nestjsx / crud

NestJs CRUD for RESTful APIs
https://github.com/nestjsx/crud/wiki
MIT License
4.09k stars 541 forks source link

Crud-Request includes array indices in the query string for join params #399

Open lothern opened 4 years ago

lothern commented 4 years ago

Team,

I've encountered an issue with the crud-request 4.4.1 package. I'm likely doing something wrong and a few days worth of searching has turned up zero results.

I'm getting array indices included in the query string from the RequestQueryBuilder object.

Example:

const queryString = RequestQueryBuilder.create({
  join: [
    { field: 'Entity1' },
    { field: 'Entity2' },
    { field: 'Entity3' }
  ]
})
.query();

Results in this query string:

"?join%5B0%5D=Entity1&join%5B1%5D=Entity2&join%5B2%5D=Entity3"

I've also done this:

const queryString = RequestQueryBuilder.create({
  join: [
    { field: 'Entity1' },
    { field: 'Entity2' },
    { field: 'Entity3' }
  ]
})
.query(false);

With this result:

"?join[0]=Entity1&join[1]=Entity2&join[2]=Entity3"

I've been unable to find another way to remove the array indices from the resulting query string other than doing a regex string replacement. What am I missing?

lothern commented 4 years ago

Ok, I've been able to resolve my issue by modifying request-query.builder.ts query method to pass some more options to the required qs stringify method.

Before example from request-query.builder.ts:

query(encode = true): string {
    if (this.queryObject[this.paramNames.search]) {
      this.queryObject[this.paramNames.filter] = undefined;
      this.queryObject[this.paramNames.or] = undefined;
    }
    this.queryString = stringify(this.queryObject, { encode });
    return this.queryString;
  }

After example from request-query.builder.ts:

query(encode = true): string {
    if (this.queryObject[this.paramNames.search]) {
      this.queryObject[this.paramNames.filter] = undefined;
      this.queryObject[this.paramNames.or] = undefined;
    }
    this.queryString = stringify(this.queryObject, { encode, indices: false });
    return this.queryString;
  }

Which results in this query string:

"?join=Entity1&join=Entity2&join=Entity3"

Is this something I should submit a pull request for? Is anyone else experiencing this issue?

lothern commented 4 years ago

Any thoughts?

michaelyali commented 4 years ago

@lothern can I ask you why you don't want an indexed array here?

lothern commented 4 years ago

Of course you may!

The indexed array query string isn't parsed by the nestjsx/crud-typeorm & nestjsx/crud packages. That is to say I don't get a "joined" response from my backend running those two packages.

Even the crud/crud-typeorm documentation states that the query string for joins doesn't have array indices: image

michaelyali commented 4 years ago

do you use the latest crud and crud-typeorm packages? because this functionality is already covered by tests and I hadn't any fails here. Also, I've tested it manually and also hadn't any issues with that :(

lothern commented 4 years ago

Yes, I'm using @nestjsx/crud@4.4.1, @nestjsx/crud-typeorm@4.4.1, and @nestjsx/crud-request@4.4.1

I appreciate you looking into this.

ImBeCiliC commented 4 years ago

I have the same issue on filtering it adds filter[0]=name||eq||imbecilic&filter[0]=status||eq||active gives me a 400 - Bad Request if i delete the indexed array from the string everything works and i get the desired result.

Thanks for your effort!

lothern commented 4 years ago

Yeah, it appears that the version of qs that crud-request depends on should be passed the indices: false option to output the correct query string for the crud & crud-typeorm packages to parse correctly.

@ImBeCiliC Have you attempted modifying the crud-request request-query.builder.js file's query function to pass the indices: false option to qs? That worked for me.

I'm curious if this is happening for more people.

zieglar commented 4 years ago

add %5B0%5D is broken my search result ....

lothern commented 4 years ago

@zieglar Were you able to resolve your broken search with any of the methods described above?

zieglar commented 4 years ago

after .query() loop for .replace(%5B${i}%5D, '') and again .replace('%5B%5D', '').replace('[]', '')