diegomvh / angular-odata

Client side OData typescript library for Angular
https://www.npmjs.com/package/angular-odata
MIT License
50 stars 14 forks source link

How to build a query with object filters using enum options? #28

Closed icapri closed 3 years ago

icapri commented 3 years ago

Hi Mr. van Haaster,

I am trying to build an odata-queries using your package with object filters and enums as follows:

filter = { filmClassification: { eq: 2 } }

My expectation is to produce the corresponding enum option like:

...?$filter=filmClassification eq 'Horror'

Besides the metadata is defined, it is produced as a number and not the corresponding string which should be set through metadata config from the package.

I would like to know how to build such query.

Thank you in advance!

Kind Regards

Kapri

diegomvh commented 3 years ago

Hi @i-kapri The library will map the values ​​of an entity using the schema definitions. You can define these schemas manually or by using ODataApiGen. On the other hand, for enums, in particular, there are two possible alternatives depending on the configuration of API #23 If you already have a schema definition created with the metadata file, it would be best to configure the library and use the enums types. Example:

res.filter({ filmClassification: { eq: FilmType.Horror} }).fetchAll().subscribe(console.log)

Regards

icapri commented 3 years ago

Hi Mr. van Haaster,

thank you for your rapid response.

I have made the suggested changes but it still doesn't work with enums. Might it be possible that I am using an old version of your package "angular-odata": "^0.17.12", where this feature is not available?

Thank you!

Kapri

icapri commented 3 years ago

P. s.: I can see through debugging that you call a method called handleValue() which doesn't change the enum values to their corresponding strings which can be found in the members of the api schema.

E. g. if I write ....filter({ filmClassification: eq FilmClassification.Horror }), the produced query is ...?$filter=filmClassification eq 2 instead of ...?$filter=filmClassification eq 'Horror'. Can it be reached through api configuration to return the corresponding string of a given enum value in the handleValue() method?

Thank you in advance for your response!

Kapri

diegomvh commented 3 years ago

You're right!!!

Sorry for the confusion, I described the behavior of enums in situations of saving or receiving an entity. To work with queries what I do is use a helper of the definition of the entity schema:

import { Component } from '@angular/core';
import { ODataSettings } from 'angular-odata';
import { PeopleService, PersonGender, PersonGenderConfig } from './trippin';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(
    private odataSettings: ODataSettings,
    private people: PeopleService
  ) {
    let personSchema = this.odataSettings.enumTypeByName<PersonGender>(PersonGenderConfig.name);
    let female = personSchema.parser.serialize(PersonGender.Female, personSchema.api.options);
    let femaleQuery = this.people.entities().filter({Gender: female});
    console.log(`${femaleQuery}`);
    femaleQuery.fetchAll().subscribe(console.log);
  }
}

I remembered this behavior and after checking a project verify the use of enums in filters so update the example.

Reviewing this functionality and with the library more "mature" I think it is not correct to call the parser directly personGenderType.parser (violate encapsulation). I think I'm going to refactor the schema (type) to continue adding methods that help to work with them in a cleaner way.

Thank you very much for the contribution to clarify the issue. Regards

diegomvh commented 3 years ago

Parser has now the encode method, you can get the parser or the schema definition and using this method in order to get a friendly url value

https://github.com/diegomvh/AngularODataEntity/blob/ab17f5b17194a298227ad0baef5e14d23d7d7f4e/src/app/app.component.ts#L144

icapri commented 3 years ago

Parser has now the encode method, you can get the parser or the schema definition and using this method in order to get a friendly url value

https://github.com/diegomvh/AngularODataEntity/blob/ab17f5b17194a298227ad0baef5e14d23d7d7f4e/src/app/app.component.ts#L144

Hi again Mr. van Haaster,

thank you for your clear answer. I have already solved my issue by using your parser.serialize() method.

Kind Regards,

I. Kapri