I am very new to Angular. I am trying to call a GET web API method upon a button click. Now I want to display the response in HTML. When I try to access the model object, it says:
Object is possibly 'null'.
Please help.
Here is my app.component.ts. Please see the GetPatientByDate
function. The function is getting called and the res
object has data.
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { Component, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { Observable } from 'rxjs';
import { PatientModel } from '../models/PatientModel.model';
import { AsyncPipe } from '@angular/common';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, HttpClientModule, AsyncPipe, FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'Patient Details';
http = inject(HttpClient);
patients$ = this.GetPatients();
//patient$ = this.GetPatientByDate();
inputValue: string = '';
patientDetail: PatientModel | null = null;
private GetPatients(): Observable<PatientModel[]> {
return this.http.get<PatientModel[]>('https://localhost:7076/api/Appointments');
}
showAlert(): void {
if (this.inputValue) {
this.http.get<PatientModel>('https://localhost:7076/api/Appointments/date?date='+this.inputValue).subscribe((res: PatientModel) => {
alert("Name:" + res.name + " && id:" + res.id + " && Appointment Date:" + res.appointmentDate);
});
} else {
alert("None");
}
}
GetPatientByDate(): void {
this.http.get<PatientModel>('https://localhost:7076/api/Appointments/date?date='+this.inputValue).subscribe((res: PatientModel) => {
this.patientDetail = res;
});
}
}
The model I have is as follows:
export interface PatientModel {
id: string;
name: string;
appointmentDate: string;
reason: string;
}
The app.component.html is as follows. Please see patientDetail.name
.
<h1>{{title}}</h1>
<br/><br/>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 15px;
}
</style>
<table>
<tr>
<td><b>ID</b></td>
<td><b>Name</b></td>
<td><b>Appointment Date</b></td>
<td><b>Reason</b></td>
</tr>
@if (patients$ | async; as patients) {
@if (patients.length > 0) {
@for (item of patients; track $index) {
<tr>
<td><p>{{ item.id }}</p></td>
<td><p>{{ item.name }}</p></td>
<td><p>{{ item.appointmentDate }}</p></td>
<td><p>{{ item.reason }}</p></td>
</tr>
}
}
@else {
<p>Nothing found</p>
}
}
</table>
<br/>
<br/>
<div ng-controller="myController">
<label for="myInput">Enter Date:</label><br>
<input type="text" id="myInput" [(ngModel)]="inputValue" placeholder="Type here...">
<br><br>
<button (click)="GetPatientByDate()">Show Alert</button>
<p>Value bound to component property: {{ inputValue }}</p>
</div>
<br/>
<p>Details:{{ patientDetail.name }}</p>
Late to the answer.
You declare the patientDetail
with PatientModel | null
type. This is usual when you are trying to access the model properties without checking for the value that is possibly null. In your tsconfig.json, I believe you are enabling strict
.
The
strict
flag enables a wide range of type checking behavior that results in stronger guarantees of program correctness. Turning this on is equivalent to enabling all of the strict mode family options, which are outlined below.
{
"compilerOptions": {
"strict": true,
...
}
}
Avoid disabling the strict
option, you should always checking the object which is possibly null before accessing its properties.
Approach 1: With @if
Note that <p>
element will not be rendered when patientDetail
is null
.
@if (patientDetail) {
<p>Details:{{patientDetail.name}}</p>
}
Approach 2 with ?.
(Optional chaining)
Note that <p>
element will be rendered, but the value after "Details" will be blank when the patientDetail
is null
.
<p>Details:{{patientDetail?.name}}</p>