Error message: "The property is not found within the specified type when using the OR operator with

Within my Angular component, I am faced with a challenge involving an Input that can be one of two types.

@Input() profile: UserProfileDetails | BusinessProfileDetails;

The structure of the profile template is straightforward and I want to avoid duplicating code by using a single template. However, due to the differences in properties between the two types, I encounter a template error.

export interface UserProfileDetails {
  createdOn: Date;
  id: string;
  name: string;
}
export interface BusinessProfileDetails {
  businessId: string;
  businessLocation: string;
  createdOn: Date;
  id: string;
  name: string;
}

In the template code:

<div>
  <h1>{{profile.name}}</h1>
  <div>{{profile.createdOn}}</div>
  <div>{{profile.id}}</div>
  <div *ngIf="profile?.businessId">{{profile.businessId}}</div>
  <div *ngIf="profile?.businessLocation">{{profile.businessLocation}}</div>
</div>

I comprehend the root cause of the error, yet I am uncertain about how to resolve it while still utilizing the or condition

@Input() profile: UserProfileDetails | BusinessProfileDetails;

Answer №1

The issue at hand is due to Angular's Template Type Checking being enabled.

When this setting is turned on, the types of objects used in the view are validated. If an object lacks a required property, it can lead to the error you're encountering.

In your scenario, because the interface UserProfileDetails does not contain certain properties used in the view, Angular is flagging references to businessId or businessLocation as errors.

There are several ways to address this issue:

  • Disable Template Type Checking (not recommended)
  • Use a generic type for the profile variable (also not preferred)
  • Utilize a pipe to cast the object type within the view (my recommendation)
<div *ngIf="(profile | castProfileType)?.businessId">{{profile.businessId}}</div>
<div *ngIf="(profile | castProfileType)?.businessLocation">{{profile.businessLocation}}</div>
@Pipe({
    name: 'castProfileType',
})
export class CastProfileTypePipe implements PipeTransform {
  transform(value: profileObject) {
    return Object.keys(value).includes('businessId') ? <BusinessProfileDetails>value : <UserProfileDetails>value
  }
}

Answer №2

If you want to experiment, consider using:

<div *ngIf="profile.hasOwnProperty('businessId')">{{profile.businessId}}</div>
<div *ngIf="profile.hasOwnProperty('businessLocation')">{{profile.businessLocation}}</div>

Answer №3

In TypeScript, when referencing properties that are common to both interfaces, you can use the | operator which is known as a union type.

Alternatively, try using an intersection type with the & operator instead.

Answer №4

To work around this issue, you can create a function that checks the attributes on the profile object using the in operator. While not the most ideal solution, this approach will allow you to maintain the requested union of interfaces:

Component

getValue(
  attribute: string,
  obj: UserProfileDetails | BusinessProfileDetails
): any {
  if (attribute in obj) {
    return obj[attribute];
  }
}

Template

<div>
  <h1>{{ profile.name }}</h1>
  <div>{{ profile.createdOn }}</div>
  <div>{{ profile.id }}</div>
  <div>{{ getValue('businessId', profile) }}</div> <!-- Consider enhancing this with a check method combined with ngIf -->
  <div>{{ getValue('businessLocation', profile) }}</div>
</div>

Answer №5

Visit the tsconfig configuration file and modify the strict mode setting to false (usually found around line 8)

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

Troubleshooting vague errors with uploading large files in Golang's net/http protocol

I've encountered a challenging error while uploading large files to a server built with Golang's default net/http package. The upload process is defined as follows: uploadForm.onsubmit = () => { const formData = new FormData(uploa ...

display saved data from ajax request

I've been working on saving data and files using ajax. Following a tutorial (link), I managed to successfully save the data in the database and the image files in the designated folder. However, I'm facing an issue where the success or error mess ...

Linking a pair of checkboxes

I am dealing with two checkboxes on my website. <input class="checkbox1" type="checkbox" name='1' id="example1" value="example1"/> and <input class="checkbox2" type="checkbox" name='2' id="example2" value="example2"/> I ...

Unable to include Authenticated Routes in react router dom

Currently, I am utilizing react-router-dom to manage routing for users who are authenticated and non-authenticated. However, I have encountered an error in Element due to missing properties. Is there a way to make withoutAuth() function properly for authe ...

Exploring React and finding the way to a specific item

I have a list of users displayed in a table. When a user clicks on a row, I want to navigate to a different component to show the details. <tbody> {this.state.clients.map(client => ( <tr className="tableRow" onClick={() => this. ...

Exploring the capabilities of Node.js functions

I'm currently exploring Node.js and struggling to understand how functions are created and used. In my code snippet: var abc={ printFirstName:function(){ console.log("My name is abc"); console.log(this===abc); //Returns true ...

Using ajax to submit a request to the controller

I'm currently developing an ASP.NET Core MVC application and have a registration page set up. My goal is to return View with errors if the model state is false: @model WebApplication2PROP.Entities.UserRegister @* For more information on enabling M ...

Tips for verifying the request body when it consists of a lone JSON array

I am in the process of verifying the content of the request by utilizing the express-validator. The entire body is a singular array, which means there isn't a specific field name. Currently, I am making use of the new version of express-validator alo ...

A promise was caught with the following error: "Error in ./Search class Search - inline template:4:0 caused by: Maximum call stack size exceeded"

As a newcomer to Angular2, I am currently developing a web application that requires three separate calls to a REST API. To test these calls, I decided to simulate the API responses by creating three JSON files with the necessary data. However, my implemen ...

I am looking for a sample code for Tizen that allows scrolling of a <div> element using the bezel

Seeking a functional web application in Tizen that can scroll a div using the rotating bezel mechanism. I have dedicated several hours to getting it to work without success. I keep revisiting the same resources for the past three days: View Link 1 View Li ...

Dynamic popup in RShiny interface with the ability to be moved around

I am currently working on a dashboard project and I am looking to implement a dynamic popup feature that can be moved around. I have been able to create a pop-up, but it remains static. I would like the flexibility for users to drag and position the popup ...

The file type input is not directing to the correct folder in Internet Explorer version 9

Could someone please assist me with this problem in IE9? After I select a file to upload, then choose another one, it shows "fakepath" in IE9. See the image below for more information: https://i.sstatic.net/QsJFk.png https://i.sstatic.net/3nWRC.png htt ...

No change in the element's text content when clicking

I'm working on creating a timer that counts down from either 15 or 30 seconds. However, I'm having trouble changing the text value when the 15 button is clicked. Can someone help me figure out what's wrong? Thank you in advance HTML <h ...

Using middleware in Express to handle GET requests

Can the request object sent to any route be accessed globally in Express, without having to explicitly access it in a .get method or similar? ...

An error is encountered with the getToken function in the Edge Runtime when using dynamic code evaluation methods such as 'eval', 'new Function', or 'WebAssembly.compile'

Working on a project that utilizes NextAuth.JS for authentication and Redux-Saga as the state manager. To enable refresh token rotation, I have created the following set of functions: get-token.ts: import { UUID } from 'crypto'; import jwt from ...

Node.js error: exceeding parameter limit encountered during bulk data upload

I've been tasked with uploading user data in bulk via a CSV file. I'm utilizing nodejs along with the express framework. Everything works smoothly when I upload a CSV file with 60 to 70 rows, but once it exceeds 70 rows, I start encountering a se ...

Tips for adjusting card content to fit its size in material ui?

I'm looking to implement Material UI cards in a grid layout, each containing a Highcharts chart as shown in this demo. However, I'm facing an issue where the content does not adjust properly when the card size is fixed. How can I resolve this? A ...

Utilizing AJAX and PHP for seamless communication, retrieve and authenticate HTTPS SSL CERTIFICATE when interacting

Recently, I successfully created a node.js REST server located at . To develop the front-end, I am utilizing a combination of html, javascript, and php. However, when I attempted to implement an SSL certificate on the front-end, a problem arose: An issue ...

Tips on Moving a Bootstrap Modal Popup with the Arrow Keys on Your Keyboard

This example showcases the integration of Bootstrap's Default Modal Popup with jQuery UI Draggable Function. The JS fiddle link provided below contains the code snippet. $(document).ready(function() { $("#btnTest").click(function() { $(&a ...

The response detail error code 2 indicates that the post method API body check has failed within the Agora REST API, resulting in

const Authorization = `Basic ${Buffer.from(`${config.CUSTOMERID}:${config.CUSTOMER_SECRET}`).toString("base64")}`; const acquire = await axios.post(`https://api.agora.io/v1/apps/${config.agoraAppId}/cloud_recording/acquire`,{ ...