Utilizing Typescript to Inject Generics and Retrieve the Name of an ES6 Module

I am currently working on developing a versatile repository using:

  • Typescript
  • ES6
  • Angular 1.x

However, I am facing challenges in determining the correct way to inject the Entity and retrieve its module name.

The main reason for needing the name: I adhere to a naming convention where a file named order-count.ts should correspond to the URL '/order/count'

Is there a solution to this problem using Typescript/Javascript?

This is what I have so far:

order-module.ts

import {App} from '../../App';
import {OrderService} from './order-service';

const module: ng.IModule = App.module('app.order', []);

module.service('orderService', OrderService);

order-service.ts

import {CrudService} from '../../shared/services/crud-service'
import {OrderCount} from '../order/entities/order-count';

export class OrderService {
    // @ngInject
    constructor(private crudService: CrudService<OrderCount>) {
        this.crudService = crudService;
    }

    getOrders() {
        var promise = this.crudService.getAll();

        promise.then(response => {
            console.log(response, 'success');
        }, error => {
            console.log(error, 'failed');
        });
    }
}

order-count.ts

import {Entity} from '../../../shared/models/entity';

export class OrderCount extends Entity {
    storeId: string;
    storeName: string;
}

entity.ts

export interface IEntity {
    id: number;
}

entity.ts

import {IEntity} from '../../module/contracts/entities/entity';

export class Entity implements IEntity {
    new() { }
    id: number;
}

crud-service.ts

'use strict';
import { Entity } from '../models/entity';
import { EndpointService } from './endpointService';

export class CrudService<TEntity extends Entity> {
    private baseCallPath: string;
    private entity: { new (): Entity };

    // @ngInject
    constructor(private endpointService: EndpointService, private $http: ng.IHttpService) {
        this.baseCallPath = new this.entity().constructor.name.replace('-', '/');
    }

    getAll(): ng.IHttpPromise<any> {
        return this.handleResponse(
            this.$http.get(this.endpointService.getUrl(this.baseCallPath)),
            'getAll'
        );
    }

    handleResponse(promise: ng.IHttpPromise<any>, callerMethodName: string): ng.IHttpPromise<any> {
        return promise.success((data: any) => {
            Array.prototype.push.apply(this.baseCallPath, data);
        }).error((reason: any) => {
            console.log(this.baseCallPath + callerMethodName, 'ERROR', reason);
        });
    }
}

endpoint-service.ts

export class EndpointService {
    private baseUri: string = 'http://localhost:3000/api/';

    getUrl(moduleName: string): string {
        return this.baseUri + moduleName;
    }
}

Answer №1

Check out this resource for guidance on setting up a generic repository using TypeScript

Answer №2

When it comes to using class names as values, you can refer to this specific question.

An advantage is that the class name can be retrieved and used with Foo.name or this.constructor.name. However, a downside is that it may not be available in all browsers and might require polyfilling. Another drawback is that minified functions may lose their original names.

One might think it would be convenient to define a function with Foo.name = 'Foo' and stick to a predefined property. But unfortunately, Function.name is originally non-configurable, making it read-only in many browsers.

If your goal is to avoid minimizing code altogether, or if you prefer not to configure the minifier to preserve class names (which is inherently flawed), it's best to avoid using Function.name for such purposes.

In Angular, a common scenario for extendible ES6/TS classes is:

export class Foo {
  static _name = 'Foo';
}

export default angular.module('app.foo', [])
  .factory('Foo', Foo)
  // if DRY is important,
  // .factory(Foo._name, Foo)
  .name;

import { Foo } from './foo';

export class Bar extends Foo {
  static _name = 'Bar';
}

export default angular.module('app.bar', []).factory('Bar', Bar).name;

import moduleFoo from './foo';
import moduleBar from './bar';

angular.module('app', [moduleFoo, moduleBar]);

Therefore, exports for Angular modules and classes should align closely, as they are not interchangeable.

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

Creating a scrolling effect similar to the Nest Thermostat

After researching countless references, I am determined to achieve a scrolling effect similar to the Nest Thermostat. I came across this solution on this JSFiddle, but unfortunately, the parent element has a fixed position that cannot be utilized within my ...

Having trouble with ion-item click not functioning in Ionic 3?

Working on my Ionic 3 project, I have encountered an issue with the ion-item click listener. The scenario is that I am adding text over a canvas and then attempting to change the style of the text (such as font-family, font-size, bold, and italic). The UI ...

Include an additional tag solely by using a specific set of keys predetermined in advance

After getting inspiration from Stackoverflow, I decided to enhance my text-box with a tagging feature. The first step was downloading and adding the http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js file to my ASP.NET web folder, allowing me to u ...

executing ajax request to call a function, encountering partial success and encountering partial failure

Apologies for the lack of clarity in the title. I currently have a search engine that utilizes an ajax function. At present, when I type "t" in the search box, only the tags containing the word "t" are displayed (for example, if I type "t", then "test" sho ...

Ways to host static content in ExpressJS for specific directories and exclude others

I need to configure my ExpressJS server to serve static files from specific paths only, excluding others. For example, I want to serve static files from all paths except /files where I only need to manipulate a file on the server. Currently, my code looks ...

What is the best way to export an overloaded function in TypeScript?

Trying to figure out how to overload a function in TypeScript so it can determine the type of arg2 based on the value of arg1. Arg1 has a list of known values. Here's a rough example of what I'm attempting: interface CatArgs {legs : number} int ...

How to iterate through a "for" loop in JavaScript using Python-Selenium?

In my current project, I am utilizing Javascript to gather data from an HTML page using Selenium. However, I am facing a challenge where I am unable to execute the multi-line for loop in the Javascript portion on my computer through Selenium with Python (S ...

Which method is more appropriate for my request - GET or POST? Or should I consider

Recently, I've been exploring the world of get and post methods and could use some guidance! Within my App.js file, there is a user text input field and a submit button. I have a couple of tasks in mind for handling this information: Retrieve a str ...

Experiencing issues with receiving null values in formData when using React hooks

Hello everyone, I am currently experiencing some challenges while utilizing React functional components hooks with formData. The issue I'm facing is that I am receiving null data in formData even though I am using useState hooks. Instead of getting th ...

Load upcoming and previous slides in advance

Currently, I have implemented a basic slideshow on my website. It functions properly, but I am interested in preloading the previous and next slides to enhance its speed. Is there anyone who can assist me with this request? ...

Tips for choosing the node_modules distribution flavor to include in your webpack bundle

Issue: Following the update of AJV.js to Version 6.4, my vendor bundle now includes the "uri-js" ESNEXT version instead of the ES5 version, causing compatibility issues with IE11. Analysis: Upon investigation, I discovered that AJV references uri-js usi ...

Generating fresh line with knockout effect

Currently in the process of developing a Single Page Application (SPA). Utilizing knockout and observable array to iterate through a json array. Encountering an issue where there are br tags present within the text, but when using data-bind="text: myVar" ...

The concept of an HTML pop-up message that hovers above the content

While working on my HTML form, I encountered an issue regarding the display of a warning message notifying users about the caps lock being on. Currently, the warning is shown correctly in a div located to the right of the text box. However, this div's ...

Guide to incorporating a fadeIn effect in Jquery triggered by a change event

Looking for some guidance on implementing a fade-in effect on a <p> tag with relevant CSS after making an AJAX call in response to a change event. Below is the current code snippet: $('#scenarioDropdownList').change(function() { var sc ...

Angular Material's floating add button feature bears a striking resemblance to the one found

Is there a way to create a design similar to the image below using Angular Material? https://i.stack.imgur.com/L3zvH.png ...

Using NestJS to pass request and response parameters

I have a function in my services set up like this: ` @Injectable() export class AppService { getVerifyToken(req: Request, res: Response) { try { let accessToken = process.env.ACCES_TOKEN_FB; let token = req.query["hub.verify_t ...

The jQuery date picker is showing an error with the function daySettings[2].replace, indicating that

Encountering a problem with the jQuery version I am using: <script src="js/Common/jquery-2.1.1.min.js" type="text/javascript"></script> <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script> The code I have writte ...

Ways to refresh a container

How do I update the box below... <div className="container team-member-tasks"> <header className="header-box"> <h1>Team Member Tasks</h1> ...after marking a task as complete using the script below. ...

Errors related to missing RxJS operators are occurring in the browser, but are not showing up in Visual Studio

Recently, I encountered a peculiar problem with my Angular4 project, which is managed under Angular-CLI and utilizes the RxJS library. Upon updating the RxJS library to version 5.5.2, the project started experiencing issues with Observable operators. The s ...

I'm having trouble with my scroll bar in a React project using JavaScript. Can anyone spot what might be causing the issue?

Attempting to create a React site for the first time, so please forgive any novice mistakes or oversights on my part. Currently, my navigation bar is fixed at the top of the page with basic hover animations. I am aiming for it to disappear when scrolling d ...