Discovering the names of parameters when using decorators

I am in the process of creating a decorator to verify the validity of certain parameters.

Below is the method I am working on,

getUsers(offset, limit, orderBy, sort){
....
}

I want to ensure that the value of orderBy is either 'createdAt' or 'updatedAt'; otherwise, an HTTP response will be returned.

Similarly, for the sort parameter, it should only be 'ASC' or 'DESC'.

Therefore, I am looking for a way to utilize a decorator to streamline this validation process and make my code more concise. Currently, I have the following block of code to perform these checks:

if (!includes(this.orderByFields, orderBy)) {
  return Utils.HttpError.badRequest(`You are allowed to order by [ ${this.orderByFields.join(', ')} ] only.`);
}

If you have any suggestions on how to achieve this using decorators, that would be greatly appreciated. Thank you in advance :-)

Answer №1

You can implement a function like the following:

type ApiFunction = (offset: number, limit: number, orderBy: string, sort: string) => any;

const orderByFields = ["createdAt", "updatedAt"];
function validateRequest() {
  return function(_target: any, _propertyName: string, descriptor: TypedPropertyDescriptor<ApiFunction>) {
    const originalMethod = descriptor.value!;
    descriptor.value = function(offset, limit, orderBy, sort) {
      if (!orderByFields.includes(orderBy)) {
        return "Bad Request";
      }
      return originalMethod.bind(this)(offset, limit, orderBy, sort);
    };
  };
}

This approach ensures that the decorator is only applied to methods with a specific signature.

For instance, you can use it as shown below:

class Foo {
  @validateRequest()
  getUsers(offset: number, limit: number, orderBy: string, sort: string): string {
    return "Result";
  }
}

In addition, consider enforcing parameter types on the type-level for orderBy and sort. If you are the sole consumer of this API, decorators may not be necessary:

function getUsers(offset: number, limit: number, orderBy: "createdAt" | "updatedAt", sort: "ASC" | "DESC") {}

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

Navigating in a Curved Path using Webkit Transition

Currently, I am working on a simple project to learn and then incorporate it into a larger project. I have a basic box that I want to move from one position to another using CSS webkit animations and the translate function for iOS hardware acceleration. I ...

The dynamic ui-sref attribute in HTML fails to execute, while the href tag functions properly

Before moving to a controller, I make a web service call to GET a request. The response from this request is stored in the variable $rootScope.userSesion. I want this web service to run every time I switch to a different view without having to duplicate th ...

Using Reactjs fetch to retrieve error message when API returns a 400 status code

In my Reactjs web application, I am utilizing a Nodejs RestAPI. Despite this connection, I am encountering issues when the API returns a status code of 400 as I am unable to access the error message it provides. The specific "errorDesc" element within the ...

Encountering SUID Sandbox Helper Issue When Running "npm start" on WSL with Electron and Typescript

Can anyone help me with this issue? I have Node v8.10.0 and I'm attempting to follow a beginner tutorial on Electron + Typescript which can be found at the following link: https://github.com/electron/electron-quick-start-typescript Here is the full e ...

Enhancing JavaScript Asynchronous Programming with EventLoop and async/await

Exploring the intricacies of how JavaScript processes asynchronous methods led me to dive into async/await. In an effort to gain a complete understanding, I crafted the following example: async function first() { console.log(9); await Promise.resolv ...

Encountering the "Component resolution failed" error in Vue 3 when using global components

When I declare my Vue components in the top level HTML file, everything works fine. Here is an example: <body> <div class='app' id='app'> <header-bar id='headerBar'></header-bar> ...

What is the quickest method for retrieving li data using selenium?

Greetings! Your attention to this post is greatly appreciated. I recently set out to gather insights on a particular news article. Out of the staggering 11,000 comments attached to the news piece, I was able to acquire data from approximately 6,000 commen ...

Grab the table headings from an HTML table and store them in variables after accessing the DOM

Looking to modify the structure of the DOM. Wanting to display table content using paragraphs instead. To achieve this, I need to extract data from each row in the table. How can I accomplish this task? <table style="width:300px"> <tr> ...

Create a new Chart.js visualization using information retrieved from an external API

Seeking to initialize a Chart.js chart with an API, I've come across tutorials that update the data post page rendering. However, I wish to update the chart before the page renders, enabling me to view the initialized chart without any reload. <tem ...

Generating log files in Angular 2 codelogs

As a newcomer to both Angular 2 and typescript, I have a desire to establish a log file in angular 2. Is it feasible to achieve this using angular 2? ...

Issue with Attaching Click Event to Dynamic Div Elements

I've implemented divs with a Click Event triggered by a value entered in a text box. See an Example Here Upon opening the page, clicking any rows will trigger an alert. However, if you change the value in the text box (Enter Number) and click load, ...

Accessing this.href from the ASP.NET code behind using Javascript

I'm trying to pass this.href from my asp.net code behind to JavaScript. When I run the code, the value appears as 'undefined' in the alert message. Can anyone help me with this issue? Page.ClientScript.RegisterStartupScript(this.GetType(), ...

Combining two request.get functions into a single one

Is there a way to combine these two functions into one? I have two APIs: /page1 and /page2. My goal is to merge the two arrays into one because the GitHub API only displays 100 objects per page. request.get({ url: 'https://api.github.com/users/an ...

Combine consecutive <p> tags within a <div> container

Can you group all adjacent <p> elements together within a <div> element? For example, assuming the following structure: <div class="content"> <p>one</p> <p>two</p> <h2> not p</h2> <p>thr ...

What is the best way to conceal or eliminate slider increments and their corresponding labels in plotly.js?

Is there a way to eliminate or conceal the step ticks and labels of the animation slider? I want to get rid of the slider's step markers (ticks) and the corresponding labels: 'Red', 'Green' and 'Blue' located beneath the ...

Is there a way to remove all JavaScript files without touching the ones in the node_module folder?

How can I delete all the javascript files in a Node.js project, excluding those within the node_module directory, regardless of the operating system? I've attempted to achieve this using the `del-cli` npm package with the following script: del '* ...

Cherrypy/Chrome: Issue with jquery ajax request remaining pending after several successful requests

My current project involves a Cherrypy server that receives a JSON array from a client via AJAX call. The server then manipulates the array and sends it back to the client. However, I've noticed an issue where after a few smooth requests, the next req ...

Retrieving the date input from a React form powered by Bootstrap

Is there a way to extract a specific timestamp in the format yyyy-mm-dd from the code snippet below? handleDateChange = e => {} <Form.Group as = {Col}> <Form.Control type = "date" value = { this.state.closingDate } onChange = { ...

The data in the filtered table is failing to revert back to its original state upon removing the filtered item from the webpage

I am currently working with an ng-multiselect dropdown to fetch data from a database. These dropdowns are being used to filter a data table on a webpage. However, I am facing an issue where when a dropdown item is selected, it correctly filters the table, ...

What is the best way to implement a dispatch function in TypeScript?

Despite my expectations, this code does not pass typechecking. Is there a way to ensure it is well typed in Typescript? const hh = { a: (_: { type: 'a' }) => '', b: (_: { type: 'b' }) => '', } as const; ex ...