Attempting to implement a typeguard in Typescript that relies on the presence of specific content within an element

Currently, I am attempting to develop a Typescript conditional that verifies if a particular word is already present in the name.

The function in question is as follows:


isOrganic() {
    for (let i = 0; i < this.items.length; i++) {
      if(this.items[i].organic) {
        if (' (Organic)' in this.items){
          this.items[i].name = this.items[i].name
        } else {
          this.items[i].name = this.items[i].name.concat(' (Organic)')
        }
      }
    }
  }

The main goal here is to determine whether the ' (Organic)' label is already part of the name. If it is, the name should be used as is. However, if it's missing, it needs to be added. Unfortunately, instead of achieving this result, the label keeps getting appended repeatedly. For instance:

Apple (Organic) (Organic) (Organic) etc...

I'm aware that the issue lies within this specific line: if (' (Organic)' in this.items)

Despite identifying the problem, I'm struggling to devise an appropriate solution through setting up the conditional statement correctly.

Answer №1

Here is a solution for your problem:

if (this.items[i].name.endsWith(' (Organic)'))

To achieve the desired outcome, make sure to access the item's name property fully. Then, utilize string methods like contains or endsWith, as the in operator does not operate directly on strings.

Complete example:

class Foo {
  constructor() {
    this.items = []
  }

  isOrganic() {
    for (let i = 0; i < this.items.length; i++) {
      if (this.items[i].organic) {
        if (this.items[i].name.endsWith(' (Organic)')){
          this.items[i].name = this.items[i].name
        } else {
          this.items[i].name = this.items[i].name.concat(' (Organic)')
        }
      }
    }
  }
}

const foo = new Foo()

// test data
foo.items = [ 
  { name: "A", organic: false },
  { name: "B", organic: true },
  { name: "C (Organic)", organic: true },
]

foo.isOrganic()
console.log(foo.items)


Furthermore, it is important to note that this code can be refactored for better clarity.

  1. Utilize a for/of loop to iterate over the array of items to avoid repetitive calls to this.items[i].
  2. Implement a single if statement that handles cases where the item is organic but lacks the specific text suffix.

class Foo {
  constructor() {
    this.items = []
  }

  isOrganic() {
    for (let item of this.items) {
      if (item.organic && !item.name.endsWith(' (Organic)')) {
        item.name = `${item.name} (Organic)`
      }
    }
  }
}

const foo = new Foo()

// test data
foo.items = [ 
  { name: "A", organic: false },
  { name: "B", organic: true },
  { name: "C (Organic)", organic: true },
]

foo.isOrganic()
console.log(foo.items)

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

Set up an event listener for when geolocation permission is approved

My Setup: I've written some basic code snippet below: const onSuccess = () => { console.log('success'); } const onError = () => { console.log('error'); } navigator.geolocation.getCurrentPosition(onSuccess, onError) ...

Exploring the mechanics behind optional chaining, known as the Elvis operator, in TypeScript. How does this feature operate within the

Can someone explain the concept of optional chaining (Elvis operator) in TypeScript and how it can be used effectively? public static getName(user: IUser){ if(user.firstName != null && user.firstName != ""){ return user.firstName; } ...

Guide on retrieving an ArrayList() from intricate function in Angular

Simplicity is the key to my question. Let's take a look at this Angular method: getAllOrdersHeaders(){ this.getAllOrdersIds().subscribe(idList=>{ idList.forEach(id=>{ this.ordersCollection.doc(id).collection('metadata&apo ...

The error message "The export named 'render' (which was imported as 'render') could not be found" appeared

Encountering an error when building a Vue project with TypeScript and Webpack, specifically the "export 'render' (imported as 'render') was not found" issue. Below is the full error code: export 'render' (imported as 'ren ...

The provided argument, which is of type 'RefObject<HTMLDivElement>', cannot be assigned to the parameter of type 'IDivPosition'

Currently, I am implementing Typescript with React. To organize my code, I've created a separate file for my custom function called DivPosition.tsx. In this setup, I am utilizing useRef to pass the reference of the div element to my function. However ...

Use contextual type when determining the return type of a function, rather than relying solely on

When using Typescript 2.2.2 (with the strictNullChecks option set to true), I encountered an unexpected behavior. Is this a bug or intentional? interface Fn { (value: any): number; } var example1: Fn = function(value) { if (value === -1) { ...

Utilizing Azure Function Model v4: Establishing a Connection with Express.js

Using Model v4 in my Azure function index.ts import { app } from "@azure/functions"; import azureFunctionHandler from "azure-aws-serverless-express"; import expressApp from "../../app"; app.http("httpTrigger1", { methods: ["GET"], route: "api/{*segme ...

Can a composite type of numbers be created without individually mentioning each one?

Is there a way to generate a union type of numbers that increase by a specific scale without explicitly listing every number in the union? Suppose I have type ScaleByEight = 8 | 16 | 24 | 32 ... 400; Would it be possible to create a utility function where ...

Can anyone explain why the Splice function is removing the element at index 1 instead of index 0 as I specified?

selectedItems= [5,47] if(this.selectedItems.length > 1) { this.selectedItems= this.selectedItems.splice(0,1); } I am attempting to remove the element at index 0 which is 5 but unexpectedly it deletes the element at index ...

Switch the Follow/Following button depending on the user's current follow status with the individual

I am currently working on a functionality to toggle between the Follow and Following buttons based on whether the current user is following another individual. I have implemented an NgIF statement in my code, but I am facing challenges in properly checking ...

Need help with creating a unit test for the Material UI slider component? An error message saying "Error: Cannot read property 'addEventListener' of null" is displayed when trying to render the component

Encountered a problem while testing the Material-UI Slider with React-Test-Renderer: Uncaught [TypeError: Cannot read property 'addEventListener' of null] Codesandbox Link import React from "react"; import { Slider } from "@materi ...

What is the best way to create a data type that enables unrestricted index retrieval while ensuring that the value retrieved will never be

By enabling the noUncheckedIndexedAccess option in TypeScript, we ensure that when accessing object properties with arbitrary keys, the value type includes both the specified type and undefined. This behavior is generally appropriate as it aligns with run ...

What is the process for defining a default value for a template-driven form input in Angular 2?

I have a simple input element in my form that requires a default initial value to be set. <input type="number" name="interest_rate" [(ngModel)]="interest_rate"> In my code, I included this.form.controls['interest_rate'].patchValue(this.a ...

Typescript eliminates the need for unnecessary source code compilation

Within directory TS 2.6.2, there are three files: interface.ts: export interface Env { x: string } index.ts: import {Env} from './interface' // importing only the interface const env: Env = {x: '1'} console.log(env.x) tsconfi ...

Each page in NextJS has a nearly identical JavaScript bundle size

After using NextJS for a considerable amount of time, I finally decided to take a closer look at the build folder and the console output when the build process is successful. To my surprise, I noticed something peculiar during one of these inspections. In ...

Use the class type or any of its derived classes rather than an object of the class itself

I have the following classes class Foo {} class A extends Foo {} class B extends Foo {} Now, I am looking to create an interface with a property named type that should be of type class rather than an instance of a class. interface Bar { type : type ...

Ways to properly assign a key in a Generic Interface as the interface key

Can someone assist me with TypeScript generics? I am wondering how to access the T["value"] field within the ActionAdd interface. type UserValue = { username: string; }; interface User { id: number; value: UserValue; } interface ActionAdd<T = unkn ...

Angular's change detection is currently inactive

I need to toggle the visibility of a button based on the value of a boolean variable using the Output property. However, I am facing an issue where the button remains hidden even after the variable is updated with a true value. Parent Component.ts showE ...

Guide on importing videojs-offset library

I am working on a component that utilizes video.js and HLS streaming in Angular. The component code is as follows: import { Component, ElementRef, AfterViewInit, ViewChild, Input, EventEmitter, Output } from '@angular/core'; import ...

The npm start command is unable to recognize the tsx file

I recently attempted to create a React app and incorporate TypeScript into it. However, upon running the app, I noticed that npm start was not recognizing the TypeScript file and failing to automatically generate tsconfig.json. Here is the sequence of ste ...