TypeScript Callback Function Example

TypeScript (and JavaScript) is a single-threaded application, and if we continue using that thread for all tasks, the user will end up waiting for other tasks that will hamper the user experience. To solve this problem, TypeScript supports callback functions to make the program asynchronous.

A callback function is a function that is passed as an argument to another function and is executed at a later time, often after the completion of a task. It allows us to execute a certain code after a particular task is completed. This helps in performing the operations that might take an unpredictable amount of time, such as reading files, making API requests, or handling user interactions.

1. Understanding a Callback Function

In TypeScript, callback functions can be created as regular functions or as arrow functions, depending on our preference and code style.

In the following code snippet, the delayMessage is a function that takes a message, a delay in milliseconds, and a callback function. After the specified delay, the message is logged, and then the callback function is executed.

function delayMessage(message: string, delay: number, callback: (msg: string) => void) {
    setTimeout(() => {
        console.log(message);
        callback(message);
    }, delay);
}

function finalCallback(message: string) {
    console.log("Callback completed for message: " + message);
}

const message: string = "Hello, World!";
delayMessage(message, 2000, finalCallback);

The program output (after 2 seconds delay):

[LOG]: "Hello, World!" 
[LOG]: "Callback completed for message: Hello, World!"

2. Creating a Callback FunctionType

A callback function type defines the signature of a function that can be used as a callback. It specifies the number and types of parameters the function should accept, as well as its return type.

To create a callback function type, we can use either an interface or a type alias. This provides clarity and type safety in the code.

2.1. Using Interface

For example, from the previous code snippet, we can create an interface of type CallbackWithMessage that takes one input string, and returns void:

interface CallbackFunction {
    (message: string): void;
}

const finalCallback: CallbackFunction = (message) => {
    console.log("Callback completed for message: " + message);
};

Now we can execute the same functionality as follows:

function delayMessage(message: string, delay: number, callback: CallbackFunction) {
    setTimeout(() => {
        console.log(message);
        callback(message);
    }, delay);
}

const message: string = "Hello, World!";
delayMessage(message, 2000, finalCallback);

2.2. Using Type Alias

We can achieve the same functionality by using the type alias for CallbackFunction.

type CallbackFunction = (message: string) => void;

const finalCallback: CallbackFunction = (message) => {
    console.log("Callback completed for message: " + message);
};

Rest everything remains same.

3. Using Callbacks with API Requests

Mostly, we will have callback function calls after a long running process such as fetching data from online REST APIs.

Let’s see an example of this usage. We have an employee service that returns employee records. The model is:

export class Employee {
  constructor(public id: number) {
  }
}

In the service class, we can create a method that can accept a parameter of function type. After the method is completed, it will execute the callback function with data that needs to be passed.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Employee } from '../model/employee';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EmployeeService {

  constructor(private http: HttpClient) { }

  public getEmployees(callBackUpdateUIElements: Function): Observable<Employee[]> {
    const url = 'http://localhost:3000/employees';

    this.http.get<Employee[]>(url).subscribe(response => {

      this.employees = response.map(item => {
        return new Employee(item.id);
      });

      callBackUpdateUIElements(this.employees);
    });
  }
}

In the component file, create callback function which needs to be executed after a service call is successfully completed.

import { Component } from '@angular/core';
import { EmployeeService } from './service/employee.service';
import { Employee } from './model/employee';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
	title = 'app';
	employees = new Array&lt;Employee&gt;();

	private callBackUpdateUIElements(employees: Employee[]) {
  		this.employees = employees;

  		//More Logic and code here
  	}

	constructor( empService:EmployeeService ) {
		empService.getEmployees(callBackUpdateUIElements);
	}
}

This example is only to demostrate that how callback functions work. Using callback in above scenario is not a good approach. Rather use RxJS Observable to respond to data change.

4. Callback Function in JavaScript

In vanilla JS code, callback functions exist in the form of timeout functions or interval functions. e.g. In this code, we are calling a JavaScript function setTimeout() which will wait for 2 seconds and then call another function named callback().

console.log("Before function call");
 
setTimeout(callback, 2000);   //Async function call through setTimeout() method
 
function callback() {
  console.log("Callback function called");
}
 
console.log("After function call");

The program output:

Before function call
After function call
Callback function called  //After 2 seconds delay

5. Conclusion

Callback functions are a foundational concept in TypeScript and JavaScript for managing asynchronous operations. They enable us to execute code after a specific task is complete, which is especially important for tasks like API requests, file operations, and event handling.

By understanding and effectively using callback functions, you can build more responsive and efficient applications that handle asynchronous tasks gracefully.

Drop me your questions in the comments section.

Happy Learning !!

Comments

Subscribe
Notify of
guest
1 Comment
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.