Is there a way to change a typescript callback into a promise?


I am looking to create a method within my class that connects to a MySQL database. I have already written my SQL code and now I want to move away from using callbacks and start implementing promises, as it is more modern.

Below is my function with callbacks (old school):

public does_player_exist(username: string, callback: any) {
    this.mysql.connect();
    this.mysql.query('USE devdb');
    this.mysql.query('SELECT p_name FROM players WHERE p_name = "'+username+'"', (err: Error, result: any[]) {
        if (result.length === 1) {
            callback(true)
        } else {
            callback(false);
        }
    });
}

Next is the method where I attempted to use a promise, but unfortunately failed:

public does_player_exist(username: string): Promise<boolean> {
    this.mysql.connect();
    this.mysql.query('USE devdb');
    return this.mysql.query('SELECT p_name FROM players WHERE p_name = "'+username+'").toPromise().then((result) => {
        return result.length === 1;
    })
}

When I invoke this method:

service.does_player_exist('test').then((result) => { console.log(result) })

I am hopeful that someone can assist me with this transition, as I am eager to embrace more modern practices and move away from the old school ways xD

Thank you in advance.

Answer №1

Start by creating a new Promise and resolve/reject it within the callback functions of the query method. Then, return this promise. As a result, the does_player_exist method will now return a Promise object, allowing you to access functions like "then".

public does_player_exist(username: string, callback: any): Promise<boolean> {
    this.mysql.connect();
    this.mysql.query('USE devdb');
    var promise = new Promise<boolean>();
    this.mysql.query('SELECT p_name FROM players WHERE p_name = "'+username+'"', (err: Error, result: any[]) {
        if (!err) promise.resolve(!!result.length);            
        else promise.reject();
    });
    return promise;
}

It is important to ensure that the Promise class is available in your environment for this code to run successfully.

Additionally, remember to sanitize your input (username) to prevent vulnerabilities in your application and protect against potential attackers.

Answer №2

Here are some tips for improving your database connection:

1. Consider using a factory function to create and reuse connections.

2. Utilize prepared statements to avoid SQL injection vulnerabilities. You can learn more about this here.

3. Try using a promise library like Bluebird or Q for easier asynchronous operations. These libraries offer handy utility methods such as promisify, which can convert callback functions into promise-returning functions.

// This snippet demonstrates how you can implement the above tips
public query() {
    this.mysql.connect();
    this.mysql.query('USE devdb');

    return Promise.promisify(this.mysql.query.bind(this.mysql))
}

public does_player_exist(username: string): Promise<boolean> {
    return this
        .query('SELECT p_name FROM players WHERE p_name = ?', [username])
        .then(result => result.length === 1);
}

Answer №3

I developed a straightforward npm package to accomplish this while maintaining type safety:

ts-promisify-callback

This solution necessitates the usage of typescript@^4.0 (upcoming release) and is currently limited to handling callbacks in the common format of (err, result) => {}.

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

Establishing a connection between Python and MySQL on a Windows operating system using

Here is the source code I am working with: import pymysql import socket conn = pymysql.connect(host='127.0.0.1', unix_socket='/tmp/mysql.sock', user='user', passwd=None, db='extractor') cur = conn.cursor() cur.execu ...

What is the best way to handle inquiries that may already contain the solution you are seeking?

As I navigate through StackOverflow, I notice that it provides suggestions of relevant questions while typing. I am interested in implementing a similar feature on another website. My questions are stored in an AWS RDS MySQL InnoDB Database and my site is ...

Exploring end-to-end testing with NestJS and Guards

I'm trying to test an endpoint called /users using nestjs, but I encountered some errors. I'm unsure how to fix the issues and make the test pass with a guard. First Issue Nest is unable to resolve dependencies of the UserModel (?). Please en ...

What's the process for validating i18n dictionaries using TypeScript?

Is there a way to enforce type checking on existing keys within dictionaries in react-i18next? This means that TypeScript will provide warnings at compile time if a key does not exist. For example: Let's say we have the following dictionary: { "f ...

Problems with the duration of Shadcn Toasts (Inspired by the react-hot-toast library)

Within a 13.4 Nextjs project (app router), utilizing Typescript and TailwindCSS. I am currently exploring the usage of toasts provided by the remarkable shadcnUI Library, which draws inspiration from react-hot-toast while adding its own unique flair. Imp ...

Uncomplicating RxJs Operators: Decoding switchMap and combineLatest

I currently have the following RxJS subscription : combineLatest([obs1$, obs2$]) .pipe( filter(val=>!!val[0] && !!val[1]), // ensuring no null values on both observables switchMap(([val1, val2]) => combineLatest([of(v1), getObs3$( ...

Navigating to the main directory in Angular 2

I am currently diving into the world of Angular 2 and attempting to create my very first application. I am following a tutorial from Barbarian Meets Coding to guide me through the process. Following the steps outlined in the tutorial, I have set up my appl ...

Managing Many-to-One Relationships in GORM

In my GO code, I have defined a struct as follows: package models //StoryStatus indicates the current state of the story type StoryStatus string const ( //Progress indicates a story is currently being written Progress StoryStatus = "progress" ...

Traversing Abstract Syntax Trees Recursively using TypeScript

Currently in the process of developing a parser that generates an AST and then traversing it through different passes. The simplified AST structure is as follows: type LiteralExpr = { readonly kind: 'literal', readonly value: number, }; type ...

"Storing a collection of PDF files in an array in TypeScript Angular - A step-by-step

Here we have an HTML code snippet that includes an input file element with Angular: <input type="file" class="btn btn-info" id="archivoPDF" #PDFfile value="Seleccionar PDF(s)" accept="application/pdf" multiple /> And this is the TypeScript code sni ...

Transforming a React component into a TypeScript Element results in an automatic 'any' type assignment due to the inability to index an expression of type 'string | number'

I am currently in the process of migrating a React component to TypeScript, but I have encountered an issue that I am struggling to resolve. I am consistently receiving an error related to accessing variantStyles[variant][color], and I cannot pinpoint the ...

Performing a JSON array query on a JSON field in Laravel version 5.4

Within the users table, there is a JSON column named "agencies" that stores data in a simple array format like: [ "0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12", "f7c748d4-8718-441e-aa69-91b890ead5ed" ], The JSON structure above is considered valid. However, whe ...

What are the steps to effectively utilize an interface within a TypeScript file that contains its own internal import?

Currently, I am in the process of developing a React JavaScript project using WebStorm and attempting to enable type hinting for our IDEs (including VS Code) by utilizing TypeScript interfaces and JSDoc annotations. Our goal is to potentially transition to ...

Definitions for nested directories within a main index.d.ts

We have developed custom typings for the latest version of material-ui@next and successfully included them in the library during the last beta release. For those interested, you can access the index.d.ts file here. However, there seems to be a problem wi ...

In what way can TS uniquely handle each element of an array as the key of an object?

I am struggling with an object that I need to have keys representing every item in the array, each linked to a value of any. Can anyone provide guidance on how to achieve this? Unfortunately, I couldn't find a solution. Here is an example for refere ...

Mysql Query Conundrum

Currently, I am developing a chatbox instant messaging system. In the table, I want to update the status when a user closes the window, indicating that they have viewed the messages sent by their friend. For each conversation, there is a unique ID, so ...

Arranging Objects by Alphabetical Order in Typescript

I am struggling with sorting a list of objects by a string property. The property values are in the format D1, D2 ... D10 ... DXX, always starting with a D followed by a number. However, when I attempt to sort the array using the following code snippet, it ...

Avoid flickering of images by properly handling the object URL when setting the image source in an asynchronous pipe

Implementing a JWT authorized endpoint for images has made it impossible to directly link to image urls in HTML. To work around this issue, we have created an async pipe that loads the image with proper authorization (handled by an HTTP interceptor, not s ...

Steps for uploading a Node.js, Express, MySQL API to a Cpanel shared hosting platform

From my understanding, the process involves excluding the node_modules folder, creating a new database in PHPMyAdmin on Cpanel and adding the credentials to the .env file, uploading the zip file to the subdomain directory and extracting it, then exporti ...

Typescript is failing to infer the definition of an object, even after conducting a thorough check

I am encountering an issue with the code structure below: interface Data { isAvailable: boolean; } const foo = (data: Data | undefined, error: boolean) => { const hasError = error || !data; if (!hasError) { if (data.isAvailable) // do so ...