Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I define the callbacks with $http when using Typescript?

My $http call looks like this and I would like to know the most flexible way to handle all of the parameters that are returned in the .success and .error?

this.$http({ url: "/api/x, method: "GET" })
   .success((??) : void => {

   })
   .error((??) : void => {

   })

The Angular documentation tells me the following are returned:

data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers – {function([headerName])} – Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.

angular.d.ts shows me:

interface IHttpPromiseCallback<T> {
        (data: T, status: number, headers: (headerName: string) => string, config: IRequestConfig): void;
    }

    interface IHttpPromiseCallbackArg<T> {
        data?: T;
        status?: number;
        headers?: (headerName: string) => string;
        config?: IRequestConfig;
        statusText?: string;
    }

But I am still confused. Has anyone used the two interfaces above to define the callbacks and how did they do it?

Ideally I would like to have something like this:

 .success((data: any, status: number, headers: (headerName: string) => string, config: any) : void => {

But using the interfaces.

Can anyone tell me if I am on the right track and if I could use the interfaces rather than having to specify the :any :number etc after the parameters.

like image 244
Samantha J T Star Avatar asked Aug 24 '14 11:08

Samantha J T Star


People also ask

How to define callback function in TypeScript?

Use Type Keyword to Declare Callback Type in TypeScript Copy type callBackFunction = () => void; This declares a function that does not take any arguments and returns nothing. Then a function that can take zero to more arguments of type any and returns nothing will be like below.

What not to do in TypeScript?

❌ Don't use any as a type unless you are in the process of migrating a JavaScript project to TypeScript. The compiler effectively treats any as “please turn off type checking for this thing”. It is similar to putting an @ts-ignore comment around every usage of the variable.


2 Answers

I realize this is a very old post, but I don't think the answers here are adequate (even for way-back-when, when this question was asked).

status is always going to be a number, so don't worry about that parameter.

You are likely seeking a way to handle the response in a strongly typed way.

The first property, data, is probably the main one you're concerned with. In your time, that .success/.error arg would be defined like:

this.$http({ url: "/api/x, method: "GET" })
   .success((response: IHttpPromiseCallbackArg<IMyInterface>) : void => {
        console.log("Hello "+ response.data.firstName);
   })
   .error((response: IHttpPromiseCallbackArg<IMyInterface>) : void => {

   })

Here in the future, .success and .error are deprecated and $http should be handled more like a standard promise:

this.$http({ url: "/api/x, method: "GET" })
    .then((response: IHttpPromiseCallbackArg<IMyInterface>) => {
        console.log("Hello "+ response.data.firstName);
    }, (response: IHttpPromiseCallbackArg<IMyInterface>) => {
        console.log("Boo, error code "+ response.status);
    });

And those are both assuming you have the data coming from your web service that fits the following:

export interface IMyInterface {
    firstName: string
}

UPDATE 12/4/2017

Whoa, it's me again from even further in the future! Now IHttpPromiseCallbackArg is deprecated. Things here in the future sure are complicated. How I long for simpler times.

(J/K it's actually easier now.)

Instead of IHttpPromiseCallbackArg<>, use: IHttpResponse<>. It appears the interface signature is mostly (completely?) the same and is a drop-in replacement.

this.$http({ url: "/api/x, method: "GET" })
    .then((response: IHttpResponse<IMyInterface>) => {
        console.log("Hello "+ response.data.firstName);
    }, (response: IHttpResponse<IMyInterface>) => {
        console.log("Boo, error code "+ response.status);
    });
like image 148
Adam Plocher Avatar answered Sep 28 '22 04:09

Adam Plocher


Here's and example for the GET:

  private getInternal<T>(url) {
        var deferred = this.$q.defer();

        this.$http({ url: url, method: "GET" })
            .success((data: T, status: number, headers: (headerName: string) => string, config: ng.IRequestConfig): void => {
                if (status == 200 && headers('location') == null && config.timeout > 200) {
                    //do something with data
                }

                return deferred.resolve(data);
            })
            .error((data: T, status: number, headers: (headerName: string) => string, config: ng.IRequestConfig): void => {
                if (status == 500 && headers('myAuth') != null && config.method == 'GET') {
                    // write to log
                }

                return deferred.reject(data);
            });
    }

Now let's say you have a service and you know your getting a specific object:

this.getInternal<mySpecObject>('service/abc').then(res => doSomethingWithData(res));
like image 40
Amir Popovich Avatar answered Sep 28 '22 05:09

Amir Popovich