odata-query icon indicating copy to clipboard operation
odata-query copied to clipboard

Support specifying types

Open MxAshUp opened this issue 8 years ago • 5 comments

I think this is an oData v4 thing. Sample code: https://github.com/devnixs/ODataAngularResources/blob/master/src/odatavalue.js

MxAshUp avatar Jul 26 '17 20:07 MxAshUp

I've been debating myself how to handle specifying the types within odata-query. So far I've been considering 2 approaches:

  1. Have the formatting occur ahead of time by exposing a named function (or functions), such as:
import buildQuery, { format } from 'odata-query';
const query = { SomeProp: format(value, 'decimal') }
buildQuery({ filter })

I like this approach but it might be difficult to detect when passing in a "pre-typed" value as a string (ex. datetime'2017-01-01T00:00:00') and when just passing in a simple string value (ex. test) as not all types follow the type'value' format (ex. decimal is 12.345M). When passing in a simple string value, we need to format it by wrapping it in single quotes ' but if we pass in the string 12.345M we would not want to add the wrapping quotes.

  1. Pass in some structure as part of the query and have the formatting occur during query build time. For example:
import buildQuery from 'odata-query';
const query = { SomeProp: { decimal: value }}
buildQuery({ filter })

I'm not sure what the structure of this object should be, and I'm not overly keen on the key being the name of the formatter (although this somewhat aligns with the equality operators and boolean string functions). We would need a known list of formatters ahead of time, which would break supporting custom types (although I've not used them myself). It also seems like this approach adds more "magic" to the query format of odata-query.

For reference, here is the list of types we need to support (there might be more):

  • guid
  • datetime
  • datetimeoffset
  • byte
  • single
  • double
  • decimal
  • boolean
  • int32
  • custom types

techniq avatar Jul 27 '17 03:07 techniq

We could also have an explicit value format: { cast: 'guid', value: '312312-3123-12-3123-123' }, see https://github.com/techniq/odata-query/pull/18

toxik avatar May 24 '18 08:05 toxik

Starting in 5.4.0 you can now pass the value as an object { type: 'guid', value: '312312-3123-12-3123-123' }. We currently support type as guid and raw (raw is provided if you want to perform all the formatting externally and not have the value quoted/escaped/etc (like a string normally would be)).

I would still like to support most of the types listed above (ex. datetime'....') before closing the issue, but they should be pretty trivial to implement now. OData/WebApi does not support these from my testing (and is predominately what I use although I'm investigating https://github.com/voronov-maxim/OdataToEntity)

techniq avatar Jun 07 '18 17:06 techniq

How is it supposed to work with the in-Operator? Am I right that currently only eq-Operator is supported?

The current implementation works with the foo and foobar filter, but not the bar filter


buildQuery({
    foo: {
        eq: {
            type: 'guid',
            value: 'value'
        }
    },
    bar: { in: {
            type: 'guid',
            value: ['bar1', 'bar2']
        }
    },
    foobar: { in: [{
            type: 'guid',
            value: 'foobar'
        }, {
            type: 'guid',
            value: 'barfoo'
        }]
    }
})

I implemented a solution for the in-operator (Commit). I don't know how you want to handle this case.

samuelportz avatar Jun 28 '18 12:06 samuelportz

@samuelportz all comparison operators except in should be supported, as in is a special convenience operator to explode into an or statement.

Your referenced fix looks good to me and would merge it in if you would send a PR.

techniq avatar Jun 28 '18 14:06 techniq