There was a TypeError error that occurred: Unable to access the property 'title' of null in Angular/Firebase

Seeking to retrieve data from Firebase's real-time database by passing values in an input form, I encountered an issue whenever I attempt to utilize

[(ngModel)]="product.title"
.

ERROR TypeError: Cannot read property 'title' of null

This code snippet is extracted from my product-form.component.html:

<div class="row">
<div class="col-md-6">
    <form #f="ngForm" (ngSubmit)="save(f.value)">
        <div class="form-group">
            <label for="title">Title</label>
            <input #title="ngModel" [(ngModel)]="product.title" name="title" id="title" type="text" class="form-control" required>
            <div class="alert alert-danger" *ngIf="title.touched && title.invalid">
                Title is required.
            </div>
        </div>
        ... (other input fields)
        <button class="btn btn-primary">Save</button>
        <button type="button" (click)="delete()" class="btn btn-danger ml-3">Delete</button>
    </form>
</div>
<div class="col-md-6">
    <div *ngIf="product.title" class="card" style="width: 18rem;">
        <img class="card-img-top" [src]="product.imageUrl" *ngIf="product.imageUrl">
        <div class="card-body">
          <h5 class="card-title">{{ product.title }}</h5>
          <p class="card-text">{{ product.price | currency:'USD': true }}</p>
        </div>
    </div>
</div>

This snippet showcases a portion of my product-form.component.ts file:

import { Product } from './../../models/product';
... (imports)

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent implements OnInit {
  ... (properties and constructor details)

  save(product) {
    if (this.id) this.productService.update(this.id, product);
    else this.productService.create(product);

    this.router.navigate(['/admin/products']);
  }

  delete() {
    ... (deletion logic)
  }

  ngOnInit(): void {
  }
}

This excerpt represents the contents of my product.service.ts file:

import { AngularFireDatabase } from '@angular/fire/database';
... (imports)

@Injectable({
  providedIn: 'root'
})
export class ProductService {
  ... (methods for CRUD operations)
}


Finally, below is the interface defined in my product.ts file:

export interface Product {
    title: string;
    price: number;
    category: string;
    imageUrl: string;
  }

Error message displayed in the browser:

core.js:4352 ERROR TypeError: Cannot read property 'title' of null

at ProductFormComponent_Template (product-form.component.html:6)*

In need of assistance to tackle this issue. Your help would be greatly appreciated!

Answer №1

It appears that the observable emitted from get(productId) is null, so it would be wise to verify this. A quick way to check would be to replace

this.productService.get(this.id).pipe(take(1)).subscribe((p: Product) => this.product = p);

with

this.productService.get(this.id).pipe(filter(x => !!x), take(1)).subscribe((p: Product) => this.product = p);

now ensuring that the observable skips any null values.

Additionally, in your template, always use product?.title instead of product.title to prevent Angular from throwing errors. This applies to all other nested fields as well.

Answer №2

Here is a potential fix for the issue:

fetchData(){
    return this.db.list('/products').snapshotChanges().map(actions=>{
      return actions.map(action=>({key: action.key, ...action.payload.val() as Product}));
    });
  }

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

Challenges in integrating a PrimeNG Angular2 component with DynamicDialogRef, as well as the difficulties encountered when attempting to do

I am currently working on implementing a component that utilizes dynamic dialog and requires a direct usage. In the DynamicDialog example, there is a constructor in the car demo list component. constructor(private carService: CarService, public ref: Dynami ...

Is it possible for prettier to substitute var with let?

One of the tools I utilize to automatically format my Typescript code is prettier. My goal is to find out if there is a way to have prettier replace all instances of 'var' with 'let' during the formatting process. Below is the script I ...

Guide on utilizing interface within a class for functional de-structuring in TypeScript

In my current project, I have a Class that contains a method which I would like to utilize in a de-structured manner, primarily due to the presence of multiple optional arguments. To maintain strict typing, I have created an Interface to define these argum ...

Dealing with type errors involving null values when using interfaces in Typescript

I encountered an issue related to the error property within the defaultState constant: interface AuthState<T = any> { auth: T; error: null | Error; loading: boolean; } export const defaultState: { auth: null | AuthState } = { auth: null, e ...

Defining assertions with specified type criteria

Looking to do something special in TypeScript with a class called Foo. I want to create a static array named bar using const assertion, where the values are restricted to the keys of Foo. This array will serve as the type for the function func while also a ...

How to automatically select an option in a dropdown based on a condition in Angular 2

Currently, I am constructing a select element within a form using an array of objects. My goal is to have one of the options automatically selected based on a specific attribute of the object (myobject.is_default). The initial template code appears as fol ...

Invoking vscode Extension to retrieve data from webview

One task I'm currently working on involves returning a list from the extension to be displayed in the input box of my webview page. The idea is for a JavaScript event within the webview to trigger the extension, receive the list object, and then rend ...

Bovine without Redis to oversee queue operations

Can Bull (used for job management) be implemented without utilizing Redis? Here is a segment of my code: @Injectable() export class MailService { private queue: Bull.Queue; private readonly queueName = 'mail'; constructor() { ...

Arranging the button next to the text input field in an Angular application

I added a button labeled "X" to a page, but it is currently positioned below a textfield. How can I use Bootstrap to align the button next to the textfield instead? https://i.sstatic.net/kbX5S.png <div class="form-group row"> <div class ...

Utilizing Angular 10 to Transform a JSON Data into a Custom String for HTML Rendering

I have received a JSON response from my backend built using Spring Boot. The "category" field in the response can either be 1 or 2, where 1 represents Notifications and 2 represents FAQs. { "pageNumber": 0, "size": 5, "totalPages&q ...

Associate the generic operator <T> with a FunctionConstructor

In my TS function, I deserialize JSON into a specific type/object by providing it with a constructor function of that type which reconstructs the object from JSON. Here is how it looks like: export function deserializeJSON<T>(JSONString: string, ty ...

Sidenav selector unable to display Angular component

I'm facing a dilemma. I have the following code in my app.component.html file: <mat-sidenav-container class="sidenav-container"> <app-sidenav></app-sidenav> <mat-sidenav-content> <app-header></app-header> ...

Applying multiple classes and conditions with Angular's NgClass directive

I am currently working on implementing a feature where the class name of a component within a div can be changed based on a button click. There are approximately five CSS classes that I would like to toggle on and off using ng-class. My main question is ...

Need help inserting an image into the div when the ngif condition is true, and when the ngif condition is false

Essentially, I have a situation where I am using an *ngIf condition on a div that also contains an image. This is for a login page where I need to display different versions based on the type of user. However, I'm facing an issue where the image does ...

ReferenceError: 'exports' is undefined in the context of Typescript Jest

I'm currently delving into unit testing with jest and encountered an error that looks like this: > npm run unit > <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="771f181012374659475947">[email protected]</ ...

API Routes - xxxx has been resolved by the API without sending back a response, potentially causing delays in request processing

While working on my frontend project, I encountered an issue with a simple API call using API routes. Whenever I try to complete the call, I face the following error which prevents my redirect from working: API resolved without sending a response for /ap ...

Using Typescript: How to access a variable beyond the scope of a loop

After creating an array, I need to access the elements outside of the loop. I am aware that they are not in the scope and using 'this.' before them does not grant access. colIdx = colIdx + this.columns.findIndex(c => c.editable); this.focusIn ...

Using TypeScript with React: Step-by-step guide to creating a ref prop

I'm currently using Ionic with React (typescript) and working on creating my custom form builder. Within this process, I've created a form that requires a ref property for referencing purposes when in use. My challenge lies in defining a prop tha ...

What steps should I take to address this issue using IONIC and TypeScript?

Running into an issue with my TypeScript code for an Ionic project. I'm attempting to pass the value of the variable (this.currentroom) from the getCurrentRoom() function to another function (getUser()) but it's not working. Here's my chat s ...

Swapping out numerical value and backslash with Angular

I am encountering an issue with replacing URL parameters in my code. Take a look at the following code snippet: getTitle() { const title = this.router.url.replace(/\D\//g, ''); return title; } However, it seems to only be removin ...