UNPKG

odata-query-builder

Version:
134 lines (115 loc) 5.13 kB
# odata-query-builder An eloquently fluent OData query builder. [![Build Status](https://travis-ci.org/jaredmahan/angular-searchFilter.svg?branch=master)](https://travis-ci.org/jaredmahan/odata-query-builder) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) ## Install ``` yarn add odata-query-builder ``` or ``` npm install --save odata-query-builder ``` ### Then in your code... ``` const query = new QueryBuilder() .count() .top(5) .skip(5) .expand('NavigationProp') .orderBy('MyPriorityProp') .filter(f => f.filterExpression('Property', 'eq', 'MyValue')) .select('My Properties') .toQuery() ``` Outputs: `?$orderby=MyPriorityProp&$top=5&$skip=5&$count=true&$expand=NavigationProp&$filter=Property eq 'MyValue'` # Filtering ## Filter Expressions Filter expresssions utilize [logical operators](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part2-url-conventions/odata-v4.01-cs01-part2-url-conventions.html#sec_LogicalOperatorExamples) to filter data on a specific property. Operator Options: - Equal: `eq` - Not Eqaul: `ne` - Greater Than: `gt` - Greater Than or Equal: `ge` - Less Than: `lt` - Less Than or Equal: `le` ``` const query = new QueryBuilder() .filter(f => f.filterExpression('Property1', 'eq', 'Value1') ).ToQuery(); ``` Outputs: `?$filter=Property1 eq 'Value1'` ## Filter Phrases Filter phrases are meant to be used with [canonical functions](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part2-url-conventions/odata-v4.01-cs01-part2-url-conventions.html#sec_CanonicalFunctions). Filter Phrasing exposes the filter as a string which allows you to inject any of the various filtering mechanisms available in `OData v4`. Below are a few examples: ``` const query = new QueryBuilder() .filter(f => .filter(f => f .filterPhrase(`contains(Property1,'Value1')`) .filterPhrase(`startswith(Property1,'Value1')`) .filterPhrase(`endswith(Property1,'Value1')`) .filterPhrase(`indexOf(Property1,'Value1') eq 1`) .filterPhrase(`length(Property1) eq 19`) .filterPhrase(`substring(Property1, 1, 2) eq 'ab'`) ).ToQuery(); ``` Outputs: `?$filter=contains(Property1,'Value1') and startswith(Property1,'Value1') and endswith(Property1,'Value1') and indexOf(Property1,'Value1') eq 1 and length(Property1) eq 19 and substring(Property1, 1, 2) eq 'ab` ## Conditional Filtering Operators By default when you utilize `.filter` you are using the `and` operator. You can be explict by passing your operator into the filter as a secondary parameter. ``` const query = new QueryBuilder().filter(f => f .filterExpression('Property1', 'eq', 'Value1') .filterExpression('Property2', 'eq', 'Value1'), 'and' ).toQuery(); ``` Outputs: `?$filter=Property1 eq 'Value1' and Property2 eq 'Value1'` ``` const query = new QueryBuilder().filter(f => f .filterExpression('Property1', 'eq', 'Value1') .filterExpression('Property2', 'eq', 'Value1'), 'or' ).toQuery(); ``` Outputs: `?$filter=Property1 eq 'Value1' or Property2 eq 'Value1'` ## Nested Filter Chaining Nested or [grouped](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part2-url-conventions/odata-v4.01-cs01-part2-url-conventions.html#sec_Grouping) filtering is used when we need to write a more complex filter for a data set. This can be done by utilizing `.and()` or `.or()` with the filter. ``` const query = new QueryBuilder().filter(f => f .filterExpression('Property1', 'eq', 'Value1') .filterExpression('Property2', 'eq', 'Value2') .and(f1 => f1 .filterExpression('Property3', 'eq', 'Value3') .filterExpression('Property4', 'eq', 'Value4') ) ).toQuery(); ``` Outputs: `?$filter=Property1 eq 'Value1' and Property2 eq 'Value2' and (Property3 eq 'Value3' and Property4 eq 'Value4')` ``` const query = new QueryBuilder().filter(f => f .filterExpression('Property1', 'eq', 'Value1') .filterExpression('Property2', 'eq', 'Value2') .or(f1 => f1 .filterExpression('Property3', 'eq', 'Value3') .filterExpression('Property4', 'eq', 'Value4') ) ).toQuery(); ``` Outputs: `?$filter=Property1 eq 'Value1' and Property2 eq 'Value2' and (Property3 eq 'Value3' or Property4 eq 'Value4')` ### Reminder: We can still explicitly control the conditional operators within each of the filters by utilizing the filter's condition operator parameter which gives us even more control over the filter. ``` const query = new QueryBuilder().filter(f => f .filterExpression('Property1', 'eq', 'Value1') .filterExpression('Property2', 'eq', 'Value2') .or(f1 => f1 .filterExpression('Property3', 'eq', 'Value3') .filterExpression('Property4', 'eq', 'Value4') ), 'and' ).toQuery(); ``` Outputs: `?$filter=Property1 eq 'Value1' and Property2 eq 'Value2' and (Property3 eq 'Value3' or Property4 eq 'Value4')`