Skip to content

Commit 32df862

Browse files
authored
Merge pull request #93 from klerick/nestjs-json-api-92
fix(json-api-nestjs): Add filter by null
2 parents 1691f06 + 3af99ff commit 32df862

File tree

4 files changed

+91
-2
lines changed

4 files changed

+91
-2
lines changed

libs/json-api/json-api-nestjs/src/lib/helper/orm/methods/get-all/get-all.spec.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {
3333
TransformDataService,
3434
TypeormUtilsService,
3535
} from '../../../../mixin/service';
36-
import { Equal, Repository } from 'typeorm';
36+
import { Equal, IsNull, Repository } from 'typeorm';
3737
import { EntityPropsMapService } from '../../../../service';
3838

3939
function getDefaultQuery<R extends Entity>() {
@@ -235,6 +235,21 @@ describe('getAll', () => {
235235
comments = await commentsRepository.find();
236236
});
237237

238+
it('Target props with null', async () => {
239+
const spyOnTransformData = jest.spyOn(
240+
transformDataService,
241+
'transformData'
242+
);
243+
244+
const query = getDefaultQuery<Users>();
245+
query.filter.target = {
246+
id: { eq: '1' },
247+
firstName: {eq: null},
248+
};
249+
await typeormService.getAll(query);
250+
expect(spyOnTransformData).toHaveBeenCalledTimes(0);
251+
});
252+
238253
it('Target props', async () => {
239254
const spyOnTransformData = jest.spyOn(
240255
transformDataService,

libs/json-api/json-api-nestjs/src/lib/helper/orm/methods/get-all/get-all.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export async function getAll<E extends Entity>(
250250
);
251251
}
252252
const resultData = await resultQuery.getMany();
253-
253+
console.log(resultData);
254254
const { included, data } =
255255
this.transformDataService.transformData(resultData);
256256
return {

libs/json-api/json-api-nestjs/src/lib/mixin/service/typeorm-utils.service.spec.ts

+58
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,64 @@ describe('TypeormUtilsService', () => {
247247
});
248248

249249
describe('getFilterExpressionForTarget', () => {
250+
it('expression for target field with null', () => {
251+
252+
const nullableField = 'id'
253+
const notNullableField = 'login'
254+
const query = getDefaultQuery<Users>();
255+
query.filter.target = {
256+
[nullableField]: {
257+
[FilterOperand.eq]: null,
258+
},
259+
[notNullableField]: {
260+
[FilterOperand.ne]: null,
261+
},
262+
};
263+
264+
function guardField<R extends any>(
265+
filter: any,
266+
field: any
267+
): asserts field is keyof R {
268+
if (filter && !(field in filter))
269+
throw new Error('field not exist in query filter');
270+
}
271+
272+
const result =
273+
typeormUtilsServiceUser.getFilterExpressionForTarget(query);
274+
const mainAliasCheck = 'Users';
275+
276+
277+
for (const item of result) {
278+
const { params, alias, expression, selectInclude } = item;
279+
expect(selectInclude).toBe(undefined);
280+
if (!alias) {
281+
expect(alias).not.toBe(undefined);
282+
throw new Error('alias in undefined for result');
283+
}
284+
const [mainAlias, field] = alias.split('.');
285+
expect(mainAlias).toBe(mainAliasCheck);
286+
guardField(query.filter.target, field);
287+
const filterName: any = query.filter.target[field];
288+
if (!filterName) {
289+
expect(filterName).not.toBe(undefined);
290+
throw new Error('filterName in undefined from query');
291+
}
292+
293+
expect(params).toBe(undefined)
294+
295+
if (field === nullableField) {
296+
expect(expression).toBe('IS NULL');
297+
continue;
298+
}
299+
300+
if (field === notNullableField) {
301+
expect(expression).toBe('IS NOT NULL');
302+
continue;
303+
}
304+
305+
throw new Error('filed is incorrect');
306+
}
307+
})
250308
it('expression for target field', () => {
251309
const valueTest = (filterOperand: FilterOperand) =>
252310
`test for ${filterOperand}`;

libs/json-api/json-api-nestjs/src/lib/mixin/service/typeorm-utils.service.ts

+16
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,22 @@ export class TypeormUtilsService<E extends Entity> {
243243
const paramsName = this.getParamName(fieldWithAlias);
244244

245245
if (!isTargetField(this._relationFields, fieldName)) {
246+
247+
if (
248+
(operand === FilterOperand.ne || operand === FilterOperand.eq) &&
249+
(valueConditional === 'null' || valueConditional === null)
250+
) {
251+
const expression = OperandMapExpressionForNull[operand].replace(
252+
EXPRESSION,
253+
paramsName
254+
);
255+
resultExpression.push({
256+
alias: fieldWithAlias,
257+
expression,
258+
});
259+
continue;
260+
}
261+
246262
const expression = OperandsMapExpression[operand].replace(
247263
EXPRESSION,
248264
paramsName

0 commit comments

Comments
 (0)