0

I have a call to my web API already written. The API returns a list of objects serialized in JSON. I know that there are fairly reasonable ways to cast individual items from JSON to typescript objects, but I cant figure out a way to do this casting to make it return a list of a typescript object.

I need to cast to a typescript object as there is a function in the object I want to be able to run, but without casting the function does not exist.

Here is the code used to retrieve the JSON:

  findTrainPage(filter = '', sortOrder = 'desc', pageNumber = 0, pageSize = 15, departStart=null, departEnd=null, origStatusWhitelist=null): Observable<Train[]>
  {
    //retrieves a page of trains to display in the train list
    let url = AppUtils.backendApiUrl() + '/trainList/getPage';
    let requestBody = { 'filter': filter, 'sortOrder': sortOrder, 'pageNum': pageNumber, 'pageSize': pageSize, 'departStart': departStart, 'departEnd': departEnd, 'origStatusWhitelist': origStatusWhitelist };
    let options = new RequestOptions({ headers: AppUtils.commonHttpHeaders() });
    let headers = { headers: AppUtils.commonHttpHeaders() };
    return this.http.post(url, requestBody, headers).map(res => res.json()).catch(error => Observable.throw(error.json()));
  }

And here is the Train object I am trying to cast to:

export class Train implements TrainInterface
{
  trainGUID: string;
  trainSymbol: string;
  createTime: string; //Should be formatted as a date, SQL table uses smalldatetime
  departTime: string;
  origStatus: OriginalStatuses;
  badGUIDFlag: boolean;
  trips: Trip[];

  private _evalStatus: EvalStatuses;
  get evalStatus(): EvalStatuses
  {
    return this.trips.reduce((min, p) => p.evalStatus < min ? p.evalStatus : min, this.trips[0].evalStatus);
  }
}

I have looked at the following SO posts:

JSON to TypeScript class instance?

Angular2 HTTP GET - Cast response into full object

0

1 Answer 1

0

Create a response wrapper class. This should match with the API response structure.

export declare class ResponseWrapper<T> {
    static SUCCESS: number;
     data: Array<T>;
}

Then map the response as follows.

 findTrainPage(filter = '', sortOrder = 'desc', pageNumber = 0, pageSize = 15, departStart = null, departEnd = null, origStatusWhitelist = null): Observable<any> {
//retrieves a page of trains to display in the train list
// let url = AppUtils.backendApiUrl() + '/trainList/getPage';
const url = 'assets/mockdata.json';
let requestBody = {
  'filter': filter,
  'sortOrder': sortOrder,
  'pageNum': pageNumber,
  'pageSize': pageSize,
  'departStart': departStart,
  'departEnd': departEnd,
  'origStatusWhitelist': origStatusWhitelist
};
let options = new RequestOptions();
return this.http.get(url)
           .map(res => res.json())
           .catch(error => Observable.throw(error.json()));

}

Usage :

trainList : Train[];

  constructor(private trainService: TrainService) {
    this.trainService.findTrainPage()
        .subscribe(data =>{
        const  resultsWrapper:ResponseWrapper<Train> = data;
        this.trainList = resultsWrapper.data;
        });
       //   error => this.errorMessage = error);
  }

Here is the tested source https://gitlab.com/supun/angular-stack-overflow-ref

Sign up to request clarification or add additional context in comments.

2 Comments

I get the following error when trying to assign resultsWrapper in the usage case: "type any[] is not assignable to type ResponseWrapper<Train[]>. Property data is missing in type any[]."
Please check my modified answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.