Developing Derived Classes in Typescript

I am looking to enhance my service class by creating a subclass where I can define functions with the same name but different implementations.

My desired structure is as follows:

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

Here is a snippet of 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, currently when I type httpWrapper., only the observable variants are displayed and not the promise-variants.

How can I achieve this?

Essentially, I would like intellisense to present the following options after typing: httpWrapper.:

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

And after selecting httpWrapper.promise.:

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

Answer №1

This is how I approached the solution:

@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);

}

Now, these functions can be invoked like so:

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

public performHttpRequests(action: Action){
    this.httpWrapper.post<Action>(endpoint, action); //returns an observable
    this.httpWrapper.get<Action>(endpoint); //returns an observable
    this.httpWrapper.delete<Action>(endpoint); //returns an observable
    this.httpWrapper.promise //classContainer
    this.httpWrapper.promise.get<Action>(endpoint); //returns a promise
    this.httpWrapper.promise.post<Action>(endpoint, action); //returns a promise
    this.httpWrapper.promise.delete<Action>(endpoint); //returns a promise
}

Answer №2

If you have an Observable<T>, you can easily convert it to a promise using the toPromise method.

Illustration

fetchData.get //by default, returns observables

fetchData.get.toPromise() //now returns a promise instead

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Finding Nested Key Paths in TypeScript for Objects and Arrays

I am in search of a unique method to create a TypeScript type that can take an object type and retrieve all the nested key paths, including properties within arrays as well. I want to exclude any default array properties such as "push" or "pop." While I ha ...

Failed to load module chunk: Please update to angular 7

I am encountering an issue with my application hosted on IIS after upgrading to Angular 7. The error message "Loading chunk module failed" indicates that instead of fetching files from the dist/ folder, it is attempting to fetch them from the root folder. ...

Adding the "unsafe" keyword before the URL in the href attribute ensures that potentially harmful URLs are

When attempting to launch an app, everything goes smoothly with a static URL. However, when using a dynamic href tag in *ngFor, the URL is modified by adding an unsafe keyword which causes it to fail. Currently operating on Angular 6, I am retrieving an I ...

Switching the LOCALE_ID in angular at runtime

One example of extensive localization support is found in the FB region setting, which accommodates hundreds of locales. How can we replicate this functionality in Angular? Would this require us to manually register all supported locales during development ...

Tips for building an interactive button with changing content and retrieving variable information when the button is clicked in an Angular framework

Received dynamic data from the server is shown below: { "data": [ { "id": 4, "first_name": "Eve", "last_name": "Holt", "lat":"25.6599899", "lng":"45.3664646", "status":"0" ...

Automatically choosing a radio button in a carousel using Angular

My Angular application includes the npm-hm-carousel. I am looking to automatically select the item in the center of the carousel, similar to the image provided. However, I also need to bind one of the ids to the selected item as I scroll through the carous ...

Ways to override a method in Angular (Version 8 and above)

I am currently working with Angular 8. My goal is to customize the method function for the following code snippet: /** * This property allows you to override the method that is used to open the login url, * allowing a way for implementations to specify ...

Using react-scripts leads TypeScript to mistakenly search for the incorrect file to import

Currently utilizing React and Relay in my project, I've encountered an issue with TypeScript. After relocating the directory where Relay generates some TypeScript files that are included in my app, TypeScript is unable to find them, presenting an unus ...

What is the proper way to create a generic class that can produce various output types while implementing a basic interface?

An abstract class is being created here to transform one type of object into another, with a simple interface comprising id:string and type:string. The intention behind the class definition is to emphasize that it will produce an assembly and during insta ...

What are the steps to make an npm package auto-imported in WebStorm?

When trying to release a simple module, the file list looks like this: |--[src] | |--[share] | |--share.moduel.ts | |--index.ts | | |--package.json |--index.ts Contents of package.json: { "name": "my-common", "version": "1.0.0", ...

Guide on transferring information from a node server connected to Google Sheets to Angular 9

Encountered an issue when trying to pass data from a Node server to the front-end using Angular 9. The server side was built with Node and data was fetched from the Google Sheet API. Despite searching extensively on Google, I couldn't find a solution ...

Compiling in Angular 2 CLI can take up a significant amount of time

Working on a rather large project using Angular 2 along with Angular 2 CLI beta 21, I can't help but be surprised by the significant compilation and updating times. Take a look at the ng serve output - it clocks in at 44.8s. $:ng serve ** NG Live De ...

Receive the [Object object] when implementing the panelbar in Angular

I am having trouble binding local data to a kendo panelbar in my Angular component. Instead of getting the correct data, all I see is [object object]. Here's a snippet from my component file: import { Component } from '@angular/core'; impor ...

Step-by-step guide on developing an AngularJs provider using TypeScript

As I've developed a Directive that incorporates various Css classes, it would greatly enhance its flexibility if the Css classes could be configured at Application start within the config section. I believe utilizing a provider is the appropriate appr ...

User update function is not being triggered by Ionic 2 Express call

I am currently working on implementing a feature in my Ionic 2 program that updates a user field when triggered. The code snippet below is from my user-service.ts file: // Update a user update(user: User): Observable<User> { let url = `${this.u ...

Converting a string to the Date class type in Angular 4: A comprehensive guide

Within my .ts file, I have a string that looks like this: const date = "5/03/2018"; I am looking to convert it into the default date format returned by Angular's Date class: Tue Apr 03 2018 20:20:12 GMT+0530 (India Standard Time) I attempted to do ...

Angular 5: Validate and combine values from multiple input fields

I have a challenge in validating multiple number input fields by calculating their sum and creating a unique Validator for Angular. Each input field is formatted like this: <input type="number" min="0" max="10"> There are several number inputs, ea ...

Executing installed packages using npm: A step-by-step guide

Recently, I have encountered a confusing issue in my coding journey. In Python, I got used to installing packages and using them right away without any hiccups. For example, with SpotDL, everything worked seamlessly. However, things took a different turn w ...

Is there a way to disable tslint warnings for npm linked packages?

Currently, I am in the process of developing a set of Angular/TypeScript components within an application that utilizes this package. To facilitate the sharing of these components, I have utilized npm link. However, upon building the project, I encountered ...

How can we prevent users from changing URLs or accessing pages directly in Angular 7 without using authguard?

Hey there! I am trying to find a way to prevent users from accessing different pages by changing the URL, like in this https://i.sstatic.net/E2e3S.png scenario. Is there a method that can redirect the user back to the same page without using Authguard or a ...