1

I want to create a subclass in my service class where I can declare functions with the same name but with different usages.

I want to be able to write:

httpWrapper.get //default is observables. returns observable
httpWrapper.promise.get //returns promise-variant

My current service:

export class HttpWrapperService {
    constructor(@Inject(HttpClient) private readonly http: HttpClient) { }

    public get<T>(endpoint: string, options?: any): Observable<HttpEvent<T>> {
        return this.http.get<T>(endpoint, options);
    }
    public post<T>(endpoint: string, data: any, options?: any): Observable<HttpEvent<T>> {
        return this.http.post<T>(endpoint, data, options);
    }
    public delete<T>(endpoint: string, options?: any): Observable<HttpEvent<T>> {
        return this.http.delete<T>(endpoint, options);
    }
}

export namespace HttpWrapperService {
    export class Promise {
        constructor(@Inject(HttpClient) private readonly http: HttpClient) { }
        public get<T>(endpoint: string, options?: any) {
            return this.http.get<T>(endpoint, options).toPromise();
        }
        public post<T>(endpoint: string, data: any, options?: any) {
            return this.http.post<T>(endpoint, data, options).toPromise();
        }
        public delete<T>(endpoint: string, options?: any) {
            return this.http.delete<T>(endpoint, options).toPromise();
        }
    }
}

However, when I write httpWrapper. I only get the observable variants. I can't choose the promise-variants.

How can I do this?

I basically want intellisense to show me when I type: httpWrapper.:

httpWrapper.post
httpWrapper.get
httpWrapper.delete
httpWrapper.promise

And when I've selected httpWrapper.promise.:

httpWrapper.promise.get
httpWrapper.promise.post
httpWrapper.promise.delete
8
  • why not simple httpWrapper.getPromise instead of httpWrapper.promise.get? Commented Feb 8, 2019 at 14:54
  • furthermore, how is httpWrapper.promise.get less repetitive than doing httpWrapper.get.toPromise()? Commented Feb 8, 2019 at 14:55
  • another tip: your wrapper service has wrong method signatures. As soons as you dont pass an options parameter or one that doesnt have the keys observe: "events" and reportProgress: true, the return type is simply Observable<T> Commented Feb 8, 2019 at 14:59
  • and if you pass one with the pair observe: 'response' then the return type will be Observable<HttpResponse<T>> Commented Feb 8, 2019 at 15:01
  • @Jota.Toledo Okay. Hold on, i will try to answer all of your questions. 1&2: readability and preferability (also, i think it is easier to refractor if functionality in the wrapper changes). 3: Not sure what you mean by this. The options param is optional? 3: what do you mean by signature parameters? 4: You lost me :/. If you have ways to help me with any problems that might occur with my current solution, I will be happy to approve it as the answer. Commented Feb 8, 2019 at 15:04

2 Answers 2

2

I solved it like this:

@Injectable()
export class HttpWrapperService {
    constructor(@Inject(HttpClient) private readonly http: HttpClient) { }

    public get<T>(endpoint: string, options?: any): Observable<HttpEvent<T>> {
        return this.http.get<T>(endpoint, options);
    }
    public post<T>(endpoint: string, data: any, options?: any): Observable<HttpEvent<T>> {
        return this.http.post<T>(endpoint, data, options);
    }
    public delete<T>(endpoint: string, options?: any): Observable<HttpEvent<T>> {
        return this.http.delete<T>(endpoint, options);
    }

    // tslint:disable-next-line:max-classes-per-file
    public promise = new class {
        constructor(private wrapper: HttpWrapperService) { }
        public get<T>(endpoint: string, options?: any) {
            return this.wrapper.get<T>(endpoint, options).toPromise();
        }
        public post<T>(endpoint: string, data: any, options?: any) {
            return this.wrapper.post<T>(endpoint, data, options).toPromise();
        }
        public delete<T>(endpoint: string, options?: any) {
            return this.wrapper.delete<T>(endpoint, options).toPromise();
        }
    }(this);

}

I can now call these functions with:

//different service
constructor(@Inject(HttpWrapperService) private readonly httpWrapper: HttpWrapperService) {}

public letsUseHttpRequests(machine: Machine){
    this.httpWrapper.post<Machine>(endpoint, machine); //observable
    this.httpWrapper.get<Machine>(endpoint); //observable
    this.httpWrapper.delete<Machine>(endpoint); //observable
    this.httpWrapper.promise //classContainer
    this.httpWrapper.promise.get<Machine>(endpoint); //promise
    this.httpWrapper.promise.post<Machine>(endpoint, machine); //promise
    this.httpWrapper.promise.delete<Machine>(endpoint); //promise
}
Sign up to request clarification or add additional context in comments.

4 Comments

Was just about to propose something similar :)
@TitianCernicova-Dragomir Even though I solved it myself - I would love to see what you had in mind, I've seen some of your other posts and I really enjoy your work. There might be other people who would like a somewhat different solution also. :)
It was literally the same, anonymous class instantiated to a field. Namespace-class merges the stuff in the namespace with the static part of the class was the extra info I would have added :)
@TitianCernicova-Dragomir Sidenote: For some reason I'm required to use HttpEvent in my observable <T>. But my other calls do not like this. How can I do my observable functions without the use of Observable<HttpEvent<T>>. Shouldn't Observable<T> work? strange...?
0

You can use toPromise method on an Observable<T>. That's it.

Example

httpWrapper.get //default is observables. returns observable

httpWrapper.get.toPromise() //returns promise-variant

Comments

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.