Developing personalized angular decorators

I've been working on creating custom decorators that can return a new instance of a class. The catch is that this class needs to be created from an injected service, and I'm struggling to access it from the decorator function.

Custom Decorator

export function Collection(endpoint: string) {
  return function (constructor: any) {
    const mainService = CollectionModule.injector.get(MainService);
    return mainService.getCollection(endpoint);
  };
}

I've been trying to get hold of the MainService from my custom decorator using the module, but the injector property seems to be missing!

The Service

@Injectable()
export class MainService {

  config;

  getCollection(endpoint: string): Collection {
    return new Collection(endpoint, this.config);
  }
}

Example Usage

export class AppComponent implements OnInit {

  @Collection('posts') postsCollection;


  ngOnInit() {
     console.log(this.postsCollection);
  }
}

Update

Check out this Stackblitz reproduction

Answer №1

When using a field decorator, the value you return is not directly assigned as the field's value.

To change the field into a property within the decorator, you can return a property descriptor that will handle retrieving the property's value.

export function Collection(endpoint: string) {
  return function (constructor: Object, propertyName: string) {
    let descriptor: PropertyDescriptor = {
      get(this: any){
        const mainService = this["_" + propertyName] || (this["_" + propertyName] =  CollectionModule.injector.get(MainService);
        return mainService
      }
    }
    return descriptor
  };
}

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

Combining Files in Angular 2 for Optimal Production Deployment

What is the best method for packaging and combining an Angular 2 application for production? My goal is to have an index.html file and a single app.min.js file. Although the Angular 2 documentation mentions using webpack, I found it to be overly complex f ...

Adding an object to a dynamic Akita store containing an Array in an Angular application can be accomplished by following these steps

Currently, I am working on storing dynamic values in an Akita store without the need to create a Model. My challenge lies in adding an object to an existing array within the store. As someone who is new to Akita, my initial approach involved deep cloning ...

A function in Typescript is created to handle diverse input types in a generic manner

My goal is to create a function that can handle various input types for abstraction purposes. type ContentA = string type ContentB = number type InputA = { name: 'method_a' content: ContentA } type InputB = { name: 'method_b' con ...

I'm attempting to retrieve an image from the database to display in the modal, but unfortunately the image isn't appearing as expected within the modal

I have the following code snippet for fetching an image: <img src="pics/file-upload-image-icon-115632290507ftgixivqp.png" id="image_preview1" class="img-thumbnail" style="margin-top: 15px; height:50%; width:20%"&g ...

The Angular 4 iframe fails to show the content from the src link webpage

Template: <iframe width="100%" height="100%" [src]="url"></iframe> Component : I have successfully converted the URL into a safeUrl: ngOnInit() { this.url = this.sanitizer.bypassSecurityTrustResourceUrl('https://www.google.com/ ...

Implementing secure access control in Angular based on user roles

Currently, we are working on integrating role-based security with Angular. However, we are looking for a solution to implement this on the server side to prevent users from accessing the page by manipulating JavaScript code in their browsers. While our se ...

The issue with ng-select arises when the placeholder option is selected, as it incorrectly sends "NULL" instead of an empty string

When searching for inventory, users have the option to refine their search using various criteria. If a user does not select any options, ng-select interprets this as "NULL," which causes an issue because the server expects an empty string in the GET reque ...

typescript Object that consists of properties from an array with a defined data type

I have an array consisting of strings. I am trying to transform this array into an object where each string is a property with specific attributes assigned to them. export interface SomeNumbers { name: string; value: number; } const arr = ['apple& ...

The width of Kendo Angular 2 grids pager and top header does not increase when scrolling

Our grids now have the horizontal scrolling feature enabled through CSS (kendo-grid {overflow: auto;}). However, we've noticed that the pager and top header of the grids do not expand their width when scrolling. Take a look at the screenshot below: ...

At what juncture is the TypeScript compiler commonly used to generate JavaScript code?

Is typescript primarily used as a pre-code deployment tool or run-time tool in its typical applications? If it's a run-time tool, is the compiling done on the client side (which seems unlikely because of the need to send down the compiler) or on the s ...

Enhancing Angular Material: requiring more user engagement for rendering to occur

Encountering an unusual issue with Angular Material: certain components require an additional event, like a click or mouse movement on the targeted div, to trigger the actual rendering process. For instance, when loading new rows in mat-table, some empty ...

display a discrete delete button when pressing a button within ng-bootstrap

My current setup uses ng-bootstrap with Angular4. Image https://i.sstatic.net/83UhP.png In the interface, a checkbox button is used to show responses fetched from the backend. By clicking the button, the x button disappears along with other elements belo ...

Retrieving a pair of data points from a Vue <select> event when it changes

I am facing an issue with a dropdown menu that is using an array with key:value pairs. I want the dropdown to only show values, but when a selection is made, I need to pass both the value and the key using the @change event. <select @change=" ...

Indicate the desired return data type directly without using a middleman variable

Occasionally, TypeScript struggles to infer the return type of a lambda or method, prompting me to manually specify it for enhanced type safety. This issue arises when dealing with promises or more complex callbacks (such as those used in the parsimmon pa ...

The custom css class is failing to be applied to a tooltip within Angular Material version 15

After updating Angular Material to version 15, I noticed that I can no longer apply custom coloring to the material tooltip. Here is an example code in .html: <button mat-raised-button matTooltip="Tooltip message" matTooltipClass="cu ...

Retrieving the active slide's property in MongoDB using Ionic React

I'm attempting to display a collection field based on the ObjectId linked to another collection in MongoDB. I have three collections: Users: { "_id" : "115ds1f4sd55fe1e51fds5f4", "name" : "Sam", &qu ...

retrieving a date from a different source and displaying it in a date

Is there a way to ensure that the date format in an input of type date always follows the dd/MM/yyyy Brazilian pattern, regardless of the computer or browser specifications? <div class="input-group input-group text-center in ...

There was a typo in the Next.js TypeScript custom Document error message: TypeError: The Document class constructor cannot be invoked without using the 'new' keyword

I encountered a problem with my website that has a customized Document by _document.js. When I tried running yarn dev, I received the error: TypeError: Class constructor Document cannot be invoked without 'new' I spent a considerable amount of t ...

Adjusting the timeout for a particular operation according to its unique identifier

I am looking for a solution to call a method that posts an answer after an input change in my Angular project. I want to reset the timeout if another input change occurs to avoid multiple posts. Is there a smart way to achieve this? My project involves po ...

Creating alignment within a form/

These two elements inexplicably gravitate towards the edge of the page. Is there a specific reason for the suitcase (only log and pass)? <div class="control-group" ng-class="{true: 'error'}[submitted && form.log.$invalid]"> & ...