apstanisic / directus-dart

Directus SDK for Dart and Flutter
MIT License
37 stars 23 forks source link

Deep Filter for translations #63

Closed svoelz closed 1 year ago

svoelz commented 1 year ago

Hello,

I am trying to deep filter my query like this deep[translations][_filter][languages_code][_eq]="en-US". Unfortunately, the deep query parameter has to be of Map<String, Query>. Is there any possibility to filter my subquery/relation?

The data structure is as follows product -> translations

I tried to use Filter.relation but it returns both languages_codes.

My code looks like this:

await directusSdk.items('product').readMany(
        query: Query(limit: 1, offset: 0, fields: ['sku', 'image', 'translations.*'] ),
        filters: Filters({'and': Filter.and([
          {'sku': Filter.eq(sku)},
          {'translations': Filter.relation('languages_code', Filter.eq(languageCode))}
        ])})
    );

Thank you for your help. I am using the apstanisic/directus-dart version 0.9.5 and directus 9.23.1.

apstanisic commented 1 year ago

Hi,

I ran your example locally and this is resulting url that I got:

/items/product?filter[_and][0][sku][_eq]=hello&filter[_and][1][translations][languages_code][_eq]=en&fields=sku,image,translations.*&limit=1&offset=0

To me it looks correct.

Filter accepts Object, so in the worst case scenario,you can simply pass path directly, something like:

  await sdk.items('product').readMany(
          filters: Filters(
            {"[translations][_filter][languages_code][_eq]": 'en'},
          ),
);

Can you provide me full url query that you are trying to achieve?

svoelz commented 1 year ago

Hi, I try to get this result: /items/product?fields[]=sku, image, translations.*&filter[sku][_eq]=xxx&filter[translations][languages_code][_eq]=en-US&deep[translations][_filter][languages_code][_eq]=en-US

The problem is, that with just filter (without deep) it returns two translations (de-DE and en-US) and not just (en-US). If I use the deep filter, it returns just en-US.

apstanisic commented 1 year ago

Oh, I see the problem.

For now, I'll try to push update that would allow you to use something like code bellow. I know it's not ideal, but it's a quick fix until proper implementation.

 final res = await sdk.items('product').readMany(
        query: Query(
// This params are passed directly to url
            customParams: {
              "deep[translations][_filter][languages_code][_eq]": "en"
            },
            limit: 1,
            offset: 0,
            fields: ['sku', 'image', 'translations.*']),
        filters: Filters({
          'and': Filter.and([
            {'sku': Filter.eq('hello')},
            {'translations': Filter.relation('languages_code', Filter.eq('en'))}
          ])
        }));
apstanisic commented 1 year ago

I published v0.11, which should enable you to do this:

    final res = await sdk.items('product').readMany(
        query: Query(customParams: {
          "deep[translations][_filter][languages_code][_eq]": "en-US",
        }, fields: [
          'sku',
          'image',
          'translations.*'
        ]),
        filters: Filters({
          'sku': Filter.eq('hello'),
          'translations': Filter.relation(
            'languages_code',
            Filter.eq('en-US'),
          ),
        }));

This will generate this url: /items/product?filter[sku][_eq]=hello&filter[translations][languages_code][_eq]=en-US&fields=sku,image,translations.*&deep[translations][_filter][languages_code][_eq]=en-US. I know it's ugly, but this is best I can do currently, without either introducing big breaking change or removing type safety for Query

svoelz commented 1 year ago

Hi, thank you. This works for me.