Dor Cohen
Dor Cohen

Reputation: 17080

How to use Angular $http with typescript generics

I'm trying to return a generic promise in the following way

public getUserPreferences: () => ng.IPromise <string> = () => {
        var promise = this.makeRequest<string>('http://someurl.com',null)
            .then((response:string) => {
                    let res: string = response;
                    return res;
                }
            )
            .catch((error) => {
            });

        return promise;
    };

        public makeRequest<T>(וrl: string, data?: any,
                          config?: any, verb?: HttpMethod): ng.IPromise<T> {
        // Cache key contains both request url and data
        var cacheKey = url + '*' + JSON.stringify(data);

        var deferred = this.$q.defer();
        var httpRequest: any;
        var responseData: T;
        var start = new Date().getTime();

        // Trying to retrieve cache data if needed
        if (!config || config.cache != false) {
            responseData = this.cacheService.get(cacheKey);
        }

        if (responseData) {
            deferred.resolve(responseData);
        }
        else {
            switch (verb) {
                case HttpMethod.GET:
                    httpRequest = this.$http.get(url, config);
                    break;
                case HttpMethod.POST:
                    httpRequest = this.$http.post(url, data, config);
                    break;
                case HttpMethod.PATCH:
                    httpRequest = this.$http.patch(url, data, config);
                    break;
                default:
                    httpRequest = this.$http.post(url, data, config);
                    break;

            }

            httpRequest
                .then((res: any) => {
                    responseData = res.data;
                    this.cacheService.put(cacheKey, responseData);
                    deferred.resolve(responseData);
                })
                .catch((error: any) => {
                    deferred.reject(error);
                });
        }

        return deferred.promise;
    }

But I'm getting the following error on getUserPreferences:

Error:(132, 9) TS2322: Type '() => IPromise' is not assignable to type '() => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. Type 'void' is not assignable to type 'string'.

Upvotes: 1

Views: 874

Answers (1)

dfsq
dfsq

Reputation: 193261

Looks like the problem is that you never resolve promise with responseData: no resolve(responseData) meant that promise was resolving implicitly with undefined.

Try this:

public makeRequest<T>(url:string, data?: any): ng.IPromise<T> {
    return this.$http.post(url, data)
           .then((res: any) => {
               return res.data;
           });
}

I also removed redundant deferred object, which you don't need because you can directly return promise.

Another difference. I dropped catch block because it's better to have it at the end of the promise chain (in getUserPreferences).

Upvotes: 1

Related Questions