Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I am using Angular 1.5.x with TypeScript. For accessing a remote API I use restangular. As a summary this is my scenario:

My API has the following resource http://localhost:53384/api/timezones. Sending a request with the verb GET to that url returns a JSON array:

[
   {
      "code":"Dateline Standard Time",
      "name":"(UTC-12:00) International Date Line West"
   },
   {
      "code":"UTC-11",
      "name":"(UTC-11:00) Coordinated Universal Time-11"
   },
   {
      "code":"Hawaiian Standard Time",
      "name":"(UTC-10:00) Hawaii"
   }
]

Now in my client AngularJs application with TypeScript:

Restangular configuration being restangularProvider: restangular.IProvider

restangularProvider.setBaseUrl("http://localhost:53384/api");

The TimeZone object representation in the client side with typescript

module app.blocks {
    "use strict";

    export class TimeZone {
        public code: string;
        public name: string;
    }
}

Factory(restangular.IService) to wrap the restangular all 'timezones' resource

module app.services {
    factory.$inject = ["Restangular"];

    function factory(restangular: restangular.IService): restangular.IElement {
        return restangular.all("timezones");
    }

    angular
        .module("app.services")
        .factory("app.services.TimeZonesRestangular", factory);
}

Service that uses TimeZonesRestangular to wrap its restangular functionality and return chained promises to whoever requests timezones in an asynchronous way

module app.services {
    "use strict";

    export interface IStaticDataService {
        getTimeZones(): ng.IPromise<app.blocks.TimeZone[]>;
    }

    class StaticDataService implements IStaticDataService {
        constructor(private timeZonesRestangular: restangular.IElement) {
        }

        public getTimeZones(): ng.IPromise<blocks.TimeZone[]> {
            return this.timeZonesRestangular.getList()
                .then((timeZones: blocks.TimeZone[]) => {
                    return timeZones;
                }, (restangularError: any) => {
                    throw "Error retrieving time zones. Status: " + restangularError.status;
                });
        }
    }

    factory.$inject = ["app.services.TimeZonesRestangular"];

    function factory(timeZonesRestangular: restangular.IElement): IStaticDataService {
        return new StaticDataService(timeZonesRestangular);
    }

    angular
        .module("app.services")
        .factory("app.services.StaticDataService", factory);
}

And finally in the controller using the service to get the 'timezones' asynchronously I have this statement

//..other controller things not relevant for this sample
this.staticDataService.getTimeZones()
      .then((timeZones: blocks.TimeZone[]) => {
            this.timeZones = timeZones;
       });

There are 2 PROBLEMS:

  1. The type definition for restangular (which I installed with tsd install restangular --resolve --save) tells me that the successCallback in the getTimeZones() method is a promiseValue: any[], which is fine because it is indeed an array. I thought it would be an array of TimeZone[] and typescript compiles properly because it accepts any[], but when debuggin I see that the successCallback promised value it's not an array of TimeZone[]. It has the properties I expected (code and name) but it also has many other things restangular-ish. An object within that array looks like this (plus some functions):

    {  
     "code":"Dateline Standard Time",
     "name":"(UTC-12:00) International Date Line West",
     "route":"timezones",
     "reqParams":null,
     "restangularized":true,
     "fromServer":true,
     "parentResource":null,
     "restangularCollection":false
    }
    

    As per https://github.com/mgonto/restangular/issues/150 it looks as if my response had been "restangularized". Scary description for somebody new to restangular like myself.. What interface in restangular type definition should I use to represent the array of restangularized TimeZone[] ?

  2. Is there any example on how to achieve something similar with TypeScript?

Thank you.

share|improve this question
up vote 0 down vote accepted

After digging a little bit further I found out that the best way to handle this is by expecting a promised value of type restangular.ICollection (which inherits from IService and Array<any>) so that I can de-restangularize the response like this:

public getTimeZones(): ng.IPromise<blocks.TimeZone[]> {
            return this.timeZonesRestangular.getList()
                .then((restangularizedTimeZones: restangular.ICollection) => {
                    return restangularizedTimeZones.plain();
                }, (restangularError: any) => {
                    throw "Error retrieving time zones. Status: " + restangularError.status;
                });
        }

Now everthing seems to be fine and the response is, indeed, a promise of TimeZone[]

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.