[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[x] Support request
[ ] Other... Please describe:
I have a backend with OData pattern and I wish to use NgEntityService, but it needs to perform the url with some minimum differences like:
GET api/heroes/5 should be GET api/heroes(5);@odata.context and data array inside value property, so I need to map every http call.Is it possible to do just extending the NgEntityService class? I'm taking a look here at the code and the url formating is very hard coded, there is no helper for it that I could override and do all other steps as it is in NgEntityService.
cheers!
Just to add what I'm currently doing.
I'm extending NgEntityService and overloading some methods:
import { NgEntityService, HttpConfig, Msg, isID } from '@datorama/akita-ng-entity-service';
import { EntityState, isDefined, getEntityType } from '@datorama/akita';
import { ODataQuery } from 'odata-fluent-query';
import * as _ from 'lodash';
/**
* Parses query string into Angular HttpParams object
* @param query ODataQuery Object
*/
export function queryToObject(query: ODataQuery<any>) {
return _(query.toString())
.split('&')
.flatMap(q => {
const [key, value] = q.split('=');
return {key, value};
})
.keyBy('key')
.mapValues('value')
.valueOf();
}
// @ts-ignore
export class ODataEntityService<S extends EntityState> extends NgEntityService<S> {
/**
*
* Get all or one entity - Creates a GET request
*
* service.get().subscribe()
* service.get({ headers, params, url })
*
* service.get(id)
* service.get(id, { headers, params, url })
*
*/
get<T = getEntityType<S>>(config?: HttpConfig & { append?: boolean } & Msg & { query?: ODataQuery<any> }): Observable<T>;
get<T = getEntityType<S>>(id?: getEntityType<S>['id'], config?: HttpConfig & { append?: boolean } & Msg & { query?: ODataQuery<any> }): Observable<T>;
get<T = getEntityType<S>>(
idOrConfig?: getEntityType<S>['id'] | HttpConfig,
config?: HttpConfig & { append?: boolean; upsert?: boolean } & Msg & { query?: ODataQuery<any> }
): Observable<T> {
const isSingle = isID(idOrConfig);
const _config: HttpConfig & { append?: boolean; upsert?: boolean } & Msg & { query?: ODataQuery<any> } = (isSingle ? config : idOrConfig) || {};
if (isSingle) {
_config.mapResponseFn = _config.mapResponseFn || (res => {
delete res['@odata.context'];
return res;
});
} else {
_config.mapResponseFn = _config.mapResponseFn || (res => res.value);
}
if (isSingle && !_config.url) {
_config.url = isSingle ? `${this.api}(${idOrConfig})` : this.api;
}
if (_config.query) {
_config.params = queryToObject(_config.query);
}
return super.get(
(isSingle ? idOrConfig : _config) as any,
_config
);
}
private resolveUrl(config: HttpConfig, id?: any) {
const customUrl = (config || {}).url;
if (isDefined(id)) {
return customUrl || `${this.api}(${id})`;
}
return customUrl || this.api;
}
}
I needed to add a new config property that is a custom helper for OData query params. It's working, but I still think it's too verbose, maybe there's a simpler way to do it.
And another problem is that I needed to override resolveUrl but it's a private method, so I needed to add @ts-ignore to prevent ts errors.
We can add a URLBuilder provider that you can override. Do you want to create a PR?
@NetanelBasal well, I can have a try... I've been thinking, what if akita had an OData module, just like akita firebase. Do you think it's worthwhile? I can help to make it solid with my experience.
Sure, you can provide it as an external package that implements EntityService, and I will add it to the official docs.
Great! Will do it
@NetanelBasal
Hi... I've been working since then to create this lib and test it. I've developed as I was working on one of my projects and I think now it's ready to be released.
The project is under https://github.com/rosostolato/akita-ng-odata-service
How can we proceed?
That's great! Publish the library, and I will link it from our official docs.
Fine! It's already published on npm. Thank you!
Added a link in our offical docs. Thanks!
Most helpful comment
Great! Will do it