-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usability problems #24
Comments
Hello.
export interface IMyData {
id: string;
name: string;
}
export interface IMyDateResourceResult extends IMyData, ResourceResult;
@ResourceParams({
url: '/api/',
path: 'v1/preview/{id}'
})
export class PreviewResource extends Resource {
@ResourceAction({ method: RequestMethod.Get })
read(data?: { id: string; }): IMyDateResourceResult { return null; }
}
let receivedData = this.previewResource.read(); The data will be added after receiving the response. {
$observable - the raw observable
$resolved: false
} And then after receiving the data the object will mutate. {
$observable: object, - the raw observable
$resolved: false,
id: 'your id'
name: 'some name'
} So you can directly map the variable to the template. Like that @Component({
// i will skip other props
template: '<div (click)="clicked(data)" *ngIf="data?.$resolved">{{data.name}}</div>'
})
export class TestComponent implements OnInit {
data:IMyDateResourceResult = null;
constructor(private previewResource: PreviewResource){}
NgOnInit() {
this.data = this.previewResource.read();
}
clicked(data:IMyDateResourceResult) {
console.log('Clocked data id:' + data.id);
}
} |
@troyanskiy thank you for so fast response. This becomes more clear... But if I use a raw export interface ResourceResult {
$resolved?: boolean;
$observable?: Observable<any>;
} That means if I use a raw Observable it won't know of the $observable.map(res => res.value).subscribe(); this res would be of $observable.map((res: IMyDateResourceResult) => res.value).subscribe(...); or do it inside of the resource: interface IMyData {
id: string;
name: string;
}
interface IMyResourceResult<T> extends ResourceResult {
$observable?: Observable<T>;
}
export interface IMyDateResourceResult extends IMyResourceResult<IMyData>, IMyData; What would be way nicer is to use this solution microsoft/TypeScript#2225 to have something similar to the following: interface Observable<T> {}
interface IMyData {
id: string;
name: string;
}
type ResourceResult<D extends {}> = D & {
$resolved?: boolean;
$observable?: Observable<D>;
}
let a: ResourceResult<IMyData> = { id: '1123', name: 'fsfdsdf' };
let b: ResourceResult<IMyData[]> = [{ id: '1123', name: 'fsfdsdf' }]; This works for both: the returned object and the observable result. And again, you don't need to have |
I understand, this might break the previous |
Thank you. |
created #30 for a not solved thingy... |
@troyanskiy still there is one problem... When I want to override e.g. an |
I will think about new way of defining members. And the new version will be v1 with removed |
@troyanskiy Thank you! I was already thinking of possible problems of a property-based notation... There is an upcoming problem which might look interesting. Assume we have the following and it works: import { Resource, ResourceAction, ResourceParams, ResourceProcessor } from 'ng2-resource-rest';
import { RequestMethod } from '@angular/http';
interface User {
id: string;
fullname: string;
}
@ResourceParams({ path: '/api/v1/preview/{id}' })
export class UserResource extends Resource {
@ResourceAction({ method: RequestMethod.Get })
public read: ResourceProcessor<{ id: string }, User>;
} Then accidentally (as it always happens) the API gets changed. The version is increased to import { Resource, ResourceAction, ResourceParams, ResourceProcessor } from 'ng2-resource-rest';
import { RequestMethod } from '@angular/http';
interface User {
id: string;
fullname: string;
firstname: string;
lastname: string;
phone: string;
}
@ResourceParams({ path: '/api/v2/preview/{id}' })
export class UserResource extends Resource {
// the same read request
@ResourceAction({ method: RequestMethod.Get })
private _read: ResourceProcessor<{ id: string }, User>;
// legacy method declaration
public read: ResourceProcessor<{ id: string }, User>;
constructor () {
this.read = (input: { id: string }) => {
let resourceResponse = this._read(input),
response = {
$resolved: false,
$observable: SomeSubject // another observable implementation
},
subscription = resourceResponse.$observable.subscribe(res => {
// actually that is why we need all this logic around
// generate the not existing anymore property
res.fullname = res.firstname + ' ' + res.lastname;
Object.assign(response, res);
subscription.unsubscribe();
});
return response;
};
}
} The problem is solvable even with a property-based resource. But still it makes sense to make kind of a proxy for some sort of these manipulations. Currently it looks awkward... What do you think? Maybe this is kind of the way to go: import { Resource, ResourceAction, ResourceParams, ResourceProcessor } from 'ng2-resource-rest';
import { RequestMethod } from '@angular/http';
interface User {
id: string;
fullname: string;
firstname: string;
lastname: string;
phone: string;
}
@ResourceParams({ path: '/api/v2/preview/{id}' })
export class UserResource extends Resource {
// the same read request
@ResourceAction({ method: RequestMethod.Get })
private _read: ResourceProcessor<{ id: string }, User>;
// legacy method declaration
public read: ResourceProcessor<{ id: string }, User>;
constructor () {
this.read = (input: { id: string }) => {
return this._read(input).$proxy(res => {
res.fullname = res.firstname + ' ' + res.lastname;
});
};
}
} |
ok, I guess this can be achieved with |
Another question: currently the |
Hi @smnbbrv |
Hi @troyanskiy This looks awesome 👍 ! I will try it as soon as I can. At first I need to finish the migration to RC6 :) |
First of all, I like the library. Thank you for you effort!
After some playing I found out some things concerning the usability improvement
1st. I'm used to define the data type inside of resource file to successfully reuse it everywhere.
E.g. wherever I call the resource I use the following:
What you offer, as I can see, does not really allow that. This is the best I could come to to make it possible
Would be nice to have something like
This allows to use the resource way smoother, encapsulates the logic and response format in the place where it should be and finally uses the TypeScript with its full power.
Also you would get rid of the array problem inside of the result, because it could be simply the part of generics:
<OnSuccess[], OnError>
2nd. Another thing I cannot understand is why instead of returning a raw
Observable
the object is returned.Observable
gives enough flexibility to check whether it is resolved or not. Is there a way to return the observable directly?3rd. Can we specify the
url
ResourceParamsBase
property in a global way for the whole application (e.g. in a bootstrap file)? Maybe it is not that useful for every project but still would be nice to haveThe text was updated successfully, but these errors were encountered: