Unusual behavior observed in the String.split() function in TypeScript

I have a TypeScript model that looks like this:

export class Product {
    id:number;
    name:string;
    brand:Brand;
    price:number;
    shippingPrice:number;
    description:string;
    photoName:string;
    productType:ProductType;
    purchaseCounter:number;
    rating:number;
    volume:string;
    ingredients:string;
}

and a json file that populates this model:

{
  "id": 1,
  "name": "xxx",
  "description": "xxx",
  "price": 12.34,
  "purchaseCounter": 12,
  "photoName": "xx",
  "shippingPrice": 12.99,
  "volume": "xxx",
  "rating": 4.7,
  "ingredients": "A,B,C",
  "brand": {
    "id": 1,
    "name": "xx"
  },
  "productType": {
    "id": 3,
    "name": "xxx"
  }
}

Now in my TypeScript component, I have a function like this :

public getIngredients():String [] {
        return this.product.ingredients.split(",");
    }

Every time I invoke this function, I encounter an error:

"TypeError: Cannot read property 'split' of undefined"

However, when I change the body of the function to something like this:

public getIngredients():String [] {
    if (this.product.ingredients == null) {
        return null;
    }
    return this.product.ingredients.split(",");
}

everything works fine and the split function works properly. Do you have any idea why checking if ingredients is not null fixes it? I must admit that I am just starting my adventure with JavaScript and TypeScript. Thanks!

UPDATE: I instantiate the Product variable here:

export class ProductOverviewComponent implements OnInit {
    private product:Product;
    private errorMessage:string;

    constructor(private productService:ProductService) {
        this.product = new Product();
    }

    ngOnInit():void {
        this.productService.getProduct()
            .subscribe(
                product => this.product = product,
                error => this.errorMessage = <any>error);
    }
}

For now, I fetch data from the JSON file but in the future, I will fetch it from the server. Another thing is that I pass the product to another component using @Input().

This is how I call the getIngredients function:

<div class="col-md-12">
        <div class="property-text">
            <ul>
                <li *ngFor="let ingredient of getIngredients()">
                    {{ ingredient }}
                </li>
            </ul>

        </div>
    </div>

Answer №1

The TypeError that occurs is a runtime JavaScript error, not related to TypeScript. This happens due to this.product.ingredients being undefined. Your solution works because in JavaScript, undefined == null evaluates to true, causing an early return in the getIngredients() function. If you were to use the === operator to compare against null, your workaround would not be effective.

The question then arises: why is this.product.ingredients undefined? It could be due to the TypeScript context of this getting lost within the getIngredients() function. Without further information from the provided code, it's challenging to determine if this is the case. You might find the article on Github titled 'this' in TypeScript helpful in addressing your issue. As a first step, consider adding console.log(this) inside getIngredients() to inspect the value of this.

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

Webpack compatibility issue hindering big.js node module functionality

I'm currently working on compiling (typescript files) and bundling my source code using webpack. Below is the content of my webpack.config.js file: const path = require('path') module.exports = { devtool: 'eval-source-map', en ...

Utilize a service to pass a parameter for querying the Rotten Tomato API

I need assistance in implementing a movie search feature using the Rotten Tomato API. My challenge lies in figuring out how to connect the $scope.nameFilter input field with my service. Here's what I have so far: View <input type="text" ng-model= ...

Activate expansive pop-up windows with primeng's dynamic dialog feature

In my Angular web application, I am using the PrimeNg modal extension to display modal popups. I have successfully passed a component to the modal service with the following code: const ref = this.dialogService.open(LogsComponent, { data: { ...

How can I utilize Luxon to calculate the total number of days that are equal to or greater than 30?

Looking at my current array structure const arr = [ { id: '1', name: 'thing1', createdAt: '2022-09-21T16:26:02Z', }, { id: '2', name: 'thing1', createdAt: '2022-11-21T16:20:20Z', } ...

Testing Angular directives using $window and $event in unit tests

My directive is simple - it overrides click behavior to trigger a full page reload. However, I am struggling to write a Unit Test for this directive. It seems like the injection of $window is not working properly, resulting in an error when running the tes ...

Pause and anticipate the subscription within the corresponding function

Is there a way to make an If-Else branch wait for all REST calls to finish, even if the Else side has no REST calls? Let's take a look at this scenario: createNewList(oldList: any[]) { const newList = []; oldList.forEach(element => { if (eleme ...

Combining QuaggaJS with Angular

I recently came across a barcode scanner known as QuaggaJS. However, as I explored the examples provided, I found myself uncertain on how to incorporate it into Angular. The demo showcased at heavily relies on jQuery. What would be the most effective me ...

Challenges with using async await alongside synchronous functions

I'm currently navigating through a library that utilizes async functions and feeling a bit overwhelmed. I'm attempting to call a function that should return a string, but I'm hitting some roadblocks. As I understand it, the ZeroEx library fu ...

A unique Angular decorator is created to seamlessly integrate a new component within an existing component

I'm currently experimenting with creating a decorator in Angular that will display a spinner on top of the main component. Essentially, my main component is making API requests and I want to overlay the decorator on top of the method. This is how I ...

Tips for passing the same value to two components using vuejs $emit

Can someone help with typing in Main, where the value can also be Test World? You can view a sample here >>> Sample The issue I'm facing is that when a user adds an item to the cart, the cart shows one more than it should. I've tried t ...

Preserve the array's status following a personalized filter in AngularJS

I am currently working with two arrays of data displayed in a tree structure and have established a relationship between them. $scope.types=['odd','prime','square','even']; $scope.items=['1','4', ...

Discovering the cause of the "Module not found" error for nrwl packages

In my project, I have integrated nrwl.io. I have set up multiple libraries: ng g lib rest //successfully created ng g lib services //successfully created ng g lib models //created without errors, but encountering "Cannot find module" issue later on! Ev ...

AngularJS input fields can be formatted to display numbers in a certain

I am facing a challenge with the input field below: <input type="text" class="span2" ng-model="mynumber"> The variable mynumber is initially set to 0.55 from a rest service when the page loads. My problem now is how to format this number for differ ...

Tips for setting the `mode` property in typeScript with VueRouter

I am a TypeScript novice and encountering a problem: export default function ({ store }) { const Router = new VueRouter({ scrollBehavior: () => ({ x: 0, y: 0 }), routes, // Keep these settings in quasar.conf.js and modify there instead! ...

The Angular ui.router does not simply overlay the view

Initially, the first state is displayed correctly, but when I click on the link to reload the view, the next state does not appear. Here is the codepen link. I modified the URL but the new content does not reload. Do you have any suggestions? ...

The angular application displays the bootstrap navbar dropdown only after the page is refreshed

I have designed a dashboard page in my Angular application with navigation links (home, about, report, profile) using Bootstrap. The dropdown menu for the Report and Profile links has a hover effect created with Bootstrap. However, the data for the hover e ...

AngularJS: Issue with Variable Value Rendering

I recently started working with Angular. In my JavaScript file, I have the following code: App.controller('ProductController', ['$scope', 'ProductService', function ($scope, ProductService) { console.clear(); console. ...

Search Filter for Live Select Dropdown in Angular JS

I have set up a newsfeed REST API to pull news items, along with a free text instant search feature. Now, I am looking to incorporate a dropdown list search filter to allow users to filter news by author. How can I integrate a dropdown filter in a similar ...

Warning message appears if date input field is left empty upon submission

After implementing angular-ui/ui-date for the date input and angular-auto-validate for form validation, I encountered an issue where the date input field shows a required message before submission. It seems that the problem may be caused by the built-in va ...

Error Encountered in Angular Unit Testing: Cannot set properties of null while trying to modify 'innerHtml' (Jasmine/Karma)

Uncaught TypeError: Cannot set properties of null (setting 'innerHtml') I am facing an issue with my Angular project where I have created a simple service to initialize the inner HTML of a div tag in the main component. This service is being cal ...