Tips for showcasing an array containing two different types of objects in Angular

After sending a request to a remote server, I am returned with a JSON array. However, the array can contain two different types of JSON objects:

[
  {
    "country": "USA",
    "caseCount": 561,
    "caseDates": [],
  },
  {
    "country": "Canada",
    "errorDescription": "Error"
  }
]

To handle this, I have created two interfaces and a variable that can hold either of these types:

export interface CountryData {
  country: string;
  caseCount: number;
  caseDates: any[];
}

export interface ErrorData {
  country: string;
  errorDescription: string;
}

countryData!: Observable<(CountryData| ErrorData)[]>;

When trying to display this data in my template with

*ngFor="let data of countryData | async"
, it only displays values common to both interfaces, such as the country field. I would like to modify this behavior to render values based on the type of the data object.

Answer №1

In order to handle different types of data in TypeScript, you need to utilize a concept known as type narrowing.

Here's an example:

interface UserData {
  username: string;
  age: number;
  email: string;
}

interface ErrorDetails {
  message: string;
}

userDataToString(data: UserData | ErrorDetails) {
  if (!data) {
    // When data is null or undefined
    return typeof data;
  } else if ('message' in data) {
    // If it's an error object
    return `ERROR: ${data.message}`;
  } else {
    // If it's user data
    return `${data.username} (${data.age} years old, email: ${data.email})`;
  }
}

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

Issue encountered while attempting to download a file using DRF with Angular integration

My current project involves using DRF and Angular. I have successfully implemented a file download feature on localhost with the following code: @action(methods=['get'], detail=True) def download(self, *args, **kwargs): instance = self.get_o ...

The specified type argument is not compatible with the ObservableInput<any> type

Struggling with an issue where the argument type (key:string) => Observable | PayloadType | is causing problems when trying to assign it to a parameter of type '(value: string, index: number) => ObersvableInput' return action$.pipe( fil ...

Creating IPv6 Mask from IPv6 Prefix Using Javascript: A Step-by-Step Guide

Write a JavaScript/TypeScript function that can convert IPv6 prefixes (ranging from 0 to 128) into the corresponding mask format (using the ffff:ffff style). Here are some examples: 33 => 'ffff:ffff:8000:0000:0000:0000:0000:0000' 128 => ...

Using the map operator in an Angular 7 application with rxjs

Despite successfully compiling my code and having everything work perfectly, I encountered an error message in my IDE (Visual Studio Code) that is preventing me from deploying my app using ng build --prod: ERROR in src/app/training/training.service.ts(6 ...

Position Bootstrap Modal in the center horizontally

I am working on an Angular project and struggling to center my Bootstrap 3 Modal horizontally on the screen. Despite trying various solutions like using text-align: center and align = "center", I have been unsuccessful. Can someone guide me on how to prope ...

Guide to setting up a datePicker in a cellEditorSelector

In my grid, I want to have different editors for different rows within the same column. The ag-Grid documentation provides information on how to achieve this using colDef.cellEditorSelector as a function: link I have successfully created unique editors fo ...

Encountering an issue while trying to execute the command "ionic cordova build android --prod --release

Currently, I am facing an issue while trying to build my apk for deployment on the Play Store. The error message is causing a time constraint and I urgently need to resolve it. Any help or suggestions regarding this matter would be greatly appreciated. ...

What is the best way to reset the testing subject between test cases using Jest and TypeScript?

I'm currently utilizing typescript alongside jest for unit testing. My goal is to create a simple unit test, but it consistently fails no matter what I try. Below is the snippet of code in question: // initialize.ts let initialized = false; let secre ...

Tips for avoiding the error message "Expected 1 arguments, but got 0" when the specified argument is actually `undefined`

Current Typescript Version: 2.6.2 I am in the process of enhancing the type safety of redux beyond what is provided by default typedefs, while also streamlining some of the redundant code. I believe I am edging closer to my desired setup, with just one is ...

How do I adjust brightness and contrast filters on a base64 URL?

When presented with an image in base64 format like this: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDAAwfqNRk/rjcYX+PxrV/wtWqwJSTlboMgAAAABJRU5ErkJggg== What is the most efficient method to programmatically alter a filter (such as brightness or cont ...

Adding multiple classes to a condition in Angular can be achieved by using the ngClass directive

Here is the code snippet I am working with: <div *ngFor="let d of getDays(); let i = index" class="day hr left" (click)="pick(d, h)" [class.white]="days[d].indexOf(h) > -1"> </div> Everything seems to be working well, but I have a ques ...

Is there a way to selectively transfer attributes and behaviors from an interface to a fresh object in typescript?

Is there a way in javascript to selectively copy properties from one object to another? I am familiar with using Object.assign() for this purpose. Specifically, I am looking to extract only the properties defined within the following interface: export in ...

Difficulty Encountered While Deploying Mean Stack Application on Heroku

I am embarking on my first journey of building a MEAN stack application, and I successfully created it locally. However, when attempting to host it on Heroku, things didn't go as planned. After researching online, I learned that both Angular and Expre ...

Having trouble with the clip-path in d3.js liquid fill gauge

Attempting to integrate the d3.js liquid fill gauge into my angular2 webapp has been a challenge. The clippath functionality seems to be malfunctioning, resulting in no wave being generated at all. https://i.stack.imgur.com/3Bmga.png instead of https://i. ...

No changes made to Observable when it's empty

I encountered an unusual issue with the rxjs "filter" in my development environment: SAP ComposableStorefront / Spartacus "~2211.21.0" angular 17.2.0 Currently, I am on a product detail page and applying a filter to my Observable in the following manner: ...

What is the process for integrating Angular files into an Express server?

I am trying to figure out how to host Angular files on my Express server. My friend created some web pages using Angular and I have an Express server set up. I have tried searching for a solution online but have not been successful. I have looked at some p ...

Steps to create an instance method that only accepts the name of another instance method

I am looking to enhance an object by adding a method that specifically accepts the name of another method within the object. How can I achieve this in a way that dynamically narrows down the accepted names of methods, without hardcoding them? Let's t ...

Async await causing failure in change detection

1. Displaying a loading animation while waiting for API data to resolve 2. Once the API response is received, turning off the loader flag and attempting to access the div element within the flag 3. The flag value is updated but the DOM is not refreshed, le ...

Angular Pipe: Working with Data Structures in Angular With Nested Arrays and Objects

After struggling to customize answers for similar questions, I find myself in need of some assistance. My current challenge involves using an angular pipe to filter the following data structure: subjects = [ { name: "subject1", keywords:[& ...

Add the component view to the webpage's body section

Using Angular 7 and ngx-bootstrap 4.0.1 Dependencies: "bootstrap": "3.3.7", "bootstrap-colorpicker": "2.5.1", "bootstrap-duallistbox": "3.0.6", "bootstrap-markdown": "2.10.0", "bootstrap-progressbar": "0.9.0", "bootstrap-slider": "9.8.0", "bootstrap-tags ...