Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Extend interface to include the type of the response #9

Open
michaelwiles opened this issue Oct 10, 2017 · 4 comments
Open

Extend interface to include the type of the response #9

michaelwiles opened this issue Oct 10, 2017 · 4 comments

Comments

@michaelwiles
Copy link

This is a feature request.

I'm wondering if it's possible to do something like:

@Injectable()
@BaseUrl('http://localhost:8080/rest/service')
export class ManagerService extends AbstractApiClient {

  constructor(protected http: Http) { super(http); }

  @Type(ResponseContentType.Json)
  @GET('/batch')
  public batches(  ): Observable<TypedResponse<Batch[]> { return; }
}

I would assume that TypedResponse would extend the current response.

With current solution all I need to do is cast the json response to that Batch[]...

const response: Observable<Response> = this.service.batches();
    response.subscribe(item => {
      const b = item.json() as Batch[];
      console.log(b[0].startTime);
    });

It would just be a lot more convenient if this was done inside. Not sure if this is possible of course.

I'm a serious newby with js and ts and have tried to have a look at where this could be put but have no clue where to start...

@gizm0bill
Copy link
Owner

Can't you already do that? there is a @Type decorator defined.
The spec for it is here (but it's tested with a blob): https://github.com/gizm0bill/angular2-rest-client/blob/master/tests/angular2-rest-client.spec.ts#L359

@michaelwiles
Copy link
Author

The @type decorator is of type ResponseContentType

It is not used for specifying the narrow type of the response. But how you want the response treated.

To support my idea you would probably need to have this type set to Json because that is the one that can be typed.

@gizm0bill
Copy link
Owner

gizm0bill commented Oct 19, 2017

Hmmm.. I see what you mean, it could be done but until I get the time to implement it maybe you could just make yourself a rxjs operator, following the example here https://netbasal.com/create-the-tojson-operator-in-angular-adaac9356e21
But keep in mind that what you are trying to do here: item.json() as Batch[] doesn't actually produce real Batch array, i.e b[0] instanceof Batch would evaluate to false, since these casts are removed after the build.
So you could implement yourself an operator something like toTypedJSON and toTypedJSONArray, basically something in the lines of this:

function toTypedJSON<T>( classRef: new() => T ): Observable<T> {
  return this.map( ( res: Response ) => Object.assign( new classRef, res.json() ) )
}

function toTypedJSONArray<T>( classRef: new() => T ): Observable<T[]> {
  return this.map( ( res: Response ) => res.json().map( item => Object.assign( new classRef, item ) ) )
}
...
this.service.batches().toTypedJSONArray(Batch)

@michaelwiles
Copy link
Author

Thanks a lot.

I'm very new to typescript/javascript so that is some new ideas for me.

Though I'm not concerned about making sure instanceOf works. My Batch type is an interface in any case so AFAIK even with this funky stuff it won't be in the javascript.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants