Struggling to grasp the Typescript syntax

I'm just starting out with Typescript and I could use some guidance in deciphering a piece of code.

The code snippet is as follows:

addSilentCallBackHandler(): void {
  this.mgr.signinSilentCallback().then(callback());    
}

function callback(): (value: any) => void | PromiseLike<void> {
  return (data: any) => {
    console.debug("callback");
  };
}

In the code, when this.mgr.signinSilentCallback() is called, it triggers the 'then' function. My goal is to pass the callback function as an argument in the addSilentCallBackHandler method. However, I am struggling with the syntax. The return type seems to be a function that again returns another function? Can someone please clarify how the callback function works?

By the way, mgr refers to the 'UserManager' within the OidcClient library, which is used for JWT token management.

Answer №1

When the callback function is called, it will return a union type. This can be a function (specifically of type (value:any) => void) OR a PromiseLike<void> object. In this context, we see that it actually returns a function. The returned function is then passed to then and will only be invoked once the Promise coming from signinSilentCallback() is resolved.

The flow goes like this: signinSilentCallback() initiates a Promise and carries out some tasks asynchronously, usually involving HTTP requests. We instruct the Promise to execute whatever is returned by callback() upon resolution. As soon as the asynchronous task completes, the Promise resolves and triggers the execution of console.debug("callback").

To enhance the example further, another option could be added to callback() where it returns a PromiseLike:

function callback(): ((value: any) => void) | PromiseLike<void> {
    // It has two possible outcomes:
    if (/*...*/) {
        // a ((value: any) => void)
        return (data: any) => {
            console.debug("callback");
        };
    } else {
        // or a PromiseLike<void>
        return new Promise<void>((resolve) => {
        console.debug("callback 2");
        resolve();
    });
}
}

If the distinction between the two types is unnecessary, it would be simpler to directly pass a function as the callback instead of creating it within another function.

addSilentCallBackHandler(): void {
   this.mgr.signinSilentCallback().then(callback);
}

function callback() {
   console.log('callback');
}

Answer №2

mgr.signinSilentCallback().then is a function that sets the on complete handler, which is a function with a parameter value.

To properly add the callback handler, you should do

this.mgr.signinSilentCallback().then(callback)
. In this way, you are passing a reference to the function. Calling it like
this.mgr.signinSilentCallback().then(callback())
would pass in the result of the function, which is a Promise.

Your callback function should just handle the response from the Promise and not return another function.

addSilentCallBackHandler(): void {
      this.mgr.signinSilentCallback().then(callback);    
  }

callback(value: any): void {
    console.debug("callback");
}

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

Extraction of properties from an object in an ES6 class

How should object destructuring be properly applied for methods within ES6 classes? user.ts import { Request, Response } from "express"; export class User { constructor (){ Object.assign(this,{ root:this.root, get:this.get ...

Failed to build development environment: Unable to assign the attribute 'fileSystem' to a null value

I'm attempting to launch an Ionic 2 Application, but I keep encountering this error when running ionic serve Error - build dev failed: Unable to assign a value to the 'fileSystem' property of object null Here is the complete log: λ ion ...

Omit certain table columns when exporting to Excel using JavaScript

I am looking to export my HTML table data into Excel sheets. After conducting a thorough research, I was able to find a solution that works for me. However, I'm facing an issue with the presence of image fields in my table data which I want to exclude ...

Enhance user interaction in Angular 13 by animating a selected element using just one animation block

I am currently working on a one-page website project to enhance my Angular skills, and I'm facing a challenge with animating multiple DOM elements using a single animation. Defining the animation for each element individually seems like a cumbersome a ...

The isAuthenticated status of the consumer remains unchanged even after being modified by a function within the AuthContext

I am working on updating the signout button in my navigation bar based on the user's authentication status. I am utilizing React Context to manage the isAuthenticated value. The AuthProvider component is wrapped in both layout.tsx and page.tsx (root f ...

Tips for executing embedded scripts within templates

I am using a controller to display the Instagram embedded code <div class="instagram_here" [innerHtml]="instagram_embeded_code"></div> However, it is only showing a blank Instagram block. https://i.stack.imgur.com/gNPDL.png I suspect there m ...

What is the process for re-exporting global.d.ts typings in a third-party JavaScript project?

Despite being able to create typings enabling my typescript modules to use function definitions from a third-party javascript module, this approach seems to cause issues for packages importing my module. To address this concern, I included the necessary t ...

Create a dropdown selection menu that is populated with options determined by the input

I have a unique situation where I need to create select options based on an integer stored in a variable inside the component.ts file. For example, let's say I have a variable called total = 10; this.totalArray = Array(this.total).fill().map((x, i) ...

Solving the issue: Angular - Troubleshooting problems when downloading files from a Web API

I'm currently working on a project that utilizes ASP.NET Core-6 Web API for the backend and Angular-14 for the frontend. My current task involves downloading a PDF file, and the code snippet for it is provided below: Backend: ASP.NET Core-6 Web API: ...

Typescript: Enhance your coding experience with intelligent parameter suggestions for functions

Within a nest.js service, there is a service method that takes an error code and generates a corresponding message to display to the user. The example below shows a simplified version of this method: getGenericErrorMessage(input: string): string { co ...

Creating Tab-Focused Accessibility in HTML Fragment (Modal Window)

I'm currently working on an Angular App with a custom Modal Dialog implementation. I'm trying to figure out how to restrict tabbing to just the elements within the Modal, rather than allowing users to tab through everything in the background. I ...

Learn the steps to dynamically show a navbar component upon logging in without the need to refresh the page using Angular 12

After logging in successfully, I want to display a navbar on my landing page. Currently, the navbar only shows up if I reload the entire page after logging in. There must be a better way to achieve this without a full page reload. app.component.html <a ...

Using nested *ngFor in combination with Bootstrap collapse features

After spending hours attempting to solve the issue, I scoured the internet in search of the correct example. Why won't the second block, where I use j for index, expand? Below is the code I am working with. <div class="col-xs-2"> <d ...

A guide on implementing Angular ngbPopover within a CellRenderer for displaying in an ag-grid cell

I successfully set up an Angular Application and decided to utilize ag-grid community as a key component for displaying data from a backend API in tables, using fontawesome icons to enhance readability. While everything looks fine and my application is fu ...

Angular failing to recognize the && operator

I have a button that opens a dialog with the blockui feature. I am trying to close the dialog and set the blockui boolean variable to false in order to stop blocking the UI. However, in my HTML code (click)="blockedDialog=false && displayAddDialog=false", ...

What is the best way to ensure an observable has finished before retrieving a value?

Looking at the function provided below: public getAssemblyTree(id: number) { .... const request = from(fetch(targetUrl.toString(), { headers: { 'responseType': 'json' }, method: 'GET' })); request.sub ...

Utilizing type guards in prop functions for conditional rendering within React TypeScript adds an extra layer

In my code, I am conditionally rendering a Button. However, I encountered an issue on line 7 where TypeScript is indicating that the first parameter of the exportExcel function may be null even though it should not be, considering the conditional render lo ...

The routing navigate method is failing to direct to the desired component

For the past day, I have been struggling to find a solution to my issue but without success. The routing seems to be malfunctioning as it keeps showing the HTML content from app.component.html even when I try changing the path in the URL. Here is a snippe ...

Volar and vue-tsc are producing conflicting TypeScript error messages

During the development of my project using Vite, Vue 3, and TypeScript, I have set up vue-tsc to run in watch mode. I am utilizing VS Code along with Volar. This setup has been helpful as it displays all TypeScript errors in the console as expected, but I ...

Encountering the error message "This expression cannot be invoked" within a Typescript React Application

I'm working on separating the logic from the layout component in my Typescript React Application, but I suspect there's an issue with the return type of my controller function. I attempted to define a type to specify the return type, but TypeScr ...