"What is the best way to determine the data type of an object retrieved from an API in TypeScript

Hey there, I'm currently developing a web application using Angular 2 and I'm focusing on implementing an exception handling mechanism. To achieve this, I've created a model that mirrors the object structure I will receive from the server (ERROR DTO).

Below is the code snippet for my error handler:

protected handleError(error, continuation: () => Observable<any>) {
        if (error.status == 401) {
            this.appContextService.redirectForLogin();
        }
        else if (typeof error == ErrorDTO) {
            return Observable.throw(error);
        }
        else {

            return Observable.throw(error);
        }
    }

It's important to note that APIs may throw objects other than my designated ErrorDTO. I need to account for this scenario in my error handling. The issue lies with the second 'else' statement where I check if typeof error == ErrorDTO, it doesn't seem to be working. I want to verify if the error DTO being received matches the type of ErrorDTO. The current implementation throws an error stating "Operator == cannot be applied to types string and type of error DTO." Could someone provide guidance on how to rectify this? Thank you.

Answer №1

It seems like your current approach may not be effective.

To clarify, when you use typeof error, it will almost always return 'object', unless the error is specifically undefined, in which case it will return 'undefined'.

You might want to consider using instanceof instead, as it functions more in line with what you are aiming for. For example,

(new Number(23)) instanceof Number
would return true.

However, if your ErrorDTO is an interface, the type information may be lost during transpilation (as interfaces cannot be used with

instanceof</code). Even if you were to declare it as a class, if the <code>error
object comes from JSON parsing, it will simply be treated as a plain object. This is because instanceof relies on prototypes to determine object instances, and all JSON-parsed objects have Object.prototype as their prototype.

One suggestion could be to handle errors differently. For instance, you could implement an errorCode property on your backend's error responses, and then create an interface in your client code:

interface BaseError {
    errorCode: number
    status: number
    // other properties...
}

Subsequently, you can have specific error interfaces extend BaseError. In this scenario, your handleError method would expect an object of type BaseError:

protected handleError(error: BaseError, continuation: () => Observable<any>) {
    if (error.status === 401) {
        // handle unauthorized error
    } else switch (error.errorCode) {
          case XXX:
             // handle specific error code XXX
             break;
          case YYY:
             // handle specific error code YYY
             break;
    }
}

I hope these suggestions prove helpful in improving your error handling process.

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

Dealing with unforeseen 'alert' scenarios within Selenium WebDriver

PS: The command driver.switchTo().alert().accept(); is not functioning as expected I am attempting to automate the testing of a webpage that displays random alerts* *random alerts: JavaScript Alerts that are uncontrolled and may appear at any time Since ...

Learn how to effortlessly move a file into a drag-and-drop area on a web page with Playwright

I am currently working with a drag-zone input element to upload files, and I am seeking a way to replicate this action using Playwright and TypeScript. I have the requirement to upload a variety of file types including txt, json, png. https://i.stack.img ...

"Creating a sleek and efficient AI chess game using chess.js with Angular's

Cannot read property 'moves' of undefine Hello there! I am currently working on developing a chess game using Angular. I'm facing an issue with the artificial intelligence in the game where the piece seems to get stuck in the mouse. The l ...

Tips for accessing the 'index' variable in *ngFor directive and making modifications (restriction on deleting only one item at a time from a list)

Here is the code snippet I'm working with: HTML: <ion-item-sliding *ngFor="let object of objectList; let idx = index"> <ion-item> <ion-input type="text" text-left [(ngModel)]="objectList[idx].name" placeholder="Nam ...

What is the best way to utilize derived types in TypeScript?

Given object A: interface A { boolProp: boolean, stringProp: string, numberProp: number, ...other props/methods... } Now, I need objects that contain one of the properties from A and set a default value for it, with other properties being irre ...

Unlocking the Power of Angular 12: Leveraging the Subscribe Method to Access Multiple REST APIs

We have a task where we need to make multiple REST API calls from the ngOnInit() method, one after the other. After making the first call, we need to pass the response to the second API call, and similarly for the third call, we need to get the value from ...

Troubleshooting the issue of conditional extension in Typescript for "Array or Object" not functioning as anticipated

My goal is to create a TypeScript type generic that has the following structure: type APIDataShape<T extends { id: unknown } | Array<{ id: unknown }>> = T extends Array<any> ? Array<{ id: T[number]["id"]; ...

Type of Data for Material UI's Selection Component

In my code, I am utilizing Material UI's Select component, which functions as a drop-down menu. Here is an example of how I am using it: const [criteria, setCriteria] = useState(''); ... let ShowUsers = () => { console.log('Wor ...

Typescript - Certain implementations may eliminate the optionality of properties

After exploring multiple versions of the Omit implementation, including the one displayed by Intellisense when hovering over Omit, I'm struggling to grasp why certain implementations are homomorphic while others are not. Through my investigation, I&a ...

Can a self-referential type truly exist?

There is a function that takes in a configuration object containing color definitions. For example: useColors({ colors: { RED: { hex: 0xff0000 }, GREEN: { hex: 0x00ff00 }, BLUE: { hex: 0x0000ff } }, doSomethingWithColor(getColor) { g ...

Creating an object efficiently by defining a pattern

As a newcomer to Typescript (and Javascript), I've been experimenting with classes. My goal is to create an object that can be filled with similar entries while maintaining type safety in a concise manner. Here is the code snippet I came up with: le ...

Elements can only be added to the array at the 0th index

In the process of developing a function, I encountered an issue where all elements added to the array were only stored in Array[0] of the rowData. The data is retrieved from a database. private createRowData() { var rowData:any[] = []; thi ...

Invoke a function within an Angular component that is passed in as a parameter

Is it possible to invoke a function using a string in JavaScript? I have a scenario where I receive a string as the function name, and I need to call and run that function. However, my current code is not working as expected. Below is the code snippet I ...

Is there a way to get this reducer function to work within a TypeScript class?

For the first advent of code challenge this year, I decided to experiment with reducers. The following code worked perfectly: export default class CalorieCounter { public static calculateMaxInventoryValue(elfInventories: number[][]): number { const s ...

Issue with ngx-extended-pdf-viewer when using URL

I'm struggling to display my PDF file on a viewer using a URL in TypeScript. I am utilizing ngx-extended-pdf-viewer. Below is a snippet of my code with the URL replaced: <ngx-extended-pdf-viewer *ngIf="!isFirefox" [src]="'http://www.chi ...

Angular: Unable to locate route declaration in the specified path /src/app/app-routing.module.ts

Whenever I attempt to set up automatic routing for components that have been created using the command below ng generate module orders --route orders --module app.module I encounter the following error message The requested URL /src/app/app-routing.mod ...

Creating a data structure that consists of pairs of elements, inspired by the alignment of domino bricks, using TypeScript syntax

My goal is to establish a type alias in TypeScript that allows all values which are arrays of Domino pairs, where each pair connects like domino bricks: Pair<A,B> connects with Pair<C,D> only if B = C. For example: const chain1: DominoChain = ...

Analyzing the type of object properties from a different perspective

I am new to TypeScript and have encountered many similar questions. I was able to find a solution, but I'm not sure if it's the most efficient one. When constructing the target object as {obj: someObject, prop: "objectPropName"}, I pas ...

Is it possible to apply a formatting filter or pipe dynamically within an *ngFor loop in Angular (versions 2 and 4

Here is the data Object within my component sampleData=[ { "value": "sample value with no formatter", "formatter": null, }, { "value": "1234.5678", "formatter": "number:'3.5-5'", }, { "value": "1.3495", "formatt ...

Encountering a TypeError while working with Next.js 14 and MongoDB: The error "res.status is not a function"

Currently working on a Next.js project that involves MongoDB integration. I am using the app router to test API calls with the code below, and surprisingly, I am receiving a response from the database. import { NextApiRequest, NextApiResponse, NextApiHandl ...