Set a value for the getter

In the component, I have a getter that looks like this:

     public get canSave(): boolean {
    const isValid = this.rows.every(r => r.phoneControl.valid);

    if (!isValid) {
      return false;
    }

    const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
    return changes.phones.changed || changes.emergencyPhone.changed;
  }

Now, in the onSubmitClick method, I need to update the value of this getter. Here is what I attempted:

    public onSubmitClick(): void {
    const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
    this.canSave = false;

    this.params
      .onSubmit(changes)
      .pipe(take(1))
      .subscribe(() => {
        this.close(true).then();
      });
  }

However, an error occurred:

Cannot assign to 'canSave' because it is a read-only property.

So, how can I update the value of canSave in the onSubmitClick method? Below is the complete code for the component:

    export class ManagePhonesPopup extends DialogBaseComponent<Params, boolean> implements OnInit {
  // Component properties and methods here

Answer №1

It seems like you are in search of a way to manipulate the return value of canSave.

One approach is to introduce two new private fields to your class:

  private _forcingCanSave = false;     // indicates if we are forcing the value
  private _forcedCanSaveValue = false; // the value to be returned when forced

You can then adjust your existing logic as follows:

  public get canSave(): boolean {
    if (this._forcingCanSave) return this._forcedCanSaveValue; // return the forced value if in "forcing mode"

    const isValid = this.rows.every(r => r.phoneControl.valid);

    if (!isValid) {
      return false;
    }

    const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
    return changes.phones.changed || changes.emergencyPhone.changed;
  }

To enable the "forcing mode," you can create a method like this:

  private forceCanSave(state: boolean) {
    this._forcingCanSave = true;
    this._forcedCanSaveValue = state;
  }

This enables overriding the value in canSave. You can use it in scenarios like this:

  public onSubmitClick(): void {
    const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
    this.forceCanSave(false); // force canSave to return false

    this.params
      .onSubmit(changes)
      .pipe(take(1))
      .subscribe(() => {
        this.close(true).then();
      });
  }

Furthermore, consider adding a method to disable the "forcing mode," such as stopForcingCanSave(), which sets this._forcingCanSave = false;. This will be useful for ending the forced behavior when needed.

Answer №2

Implement a private property named _canSave and ensure it is updated correctly within the onSubmitClick function.

export class ManagePhonesPopup extends DialogBaseComponent<Params, boolean> implements OnInit {
      public override params!: Params;
      public rows: IPhoneRow[] = [];
    
      private _canSave: boolean = false; // Private property to track save status
    
      public get canSave(): boolean {
        const isValid = this.rows.every(r => r.phoneControl.valid);
    if (this._canSave === false) {
      return false;
     }
        if (!isValid) {
          return false;
        }
    
        const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
        return this._canSave || changes.phones.changed || changes.emergencyPhone.changed;
      }
    
      constructor(
        dialog: DialogRef,
        confirmDialog: ConfirmDialogService,
        private readonly managePhonesPopupService: ManagePhonesPopupService,
      ) {
        super(dialog, confirmDialog);
      }
    
      public ngOnInit(): void {
        this.initRows(this.params.phones, this params.emergencyPhone);
      }
    
      public onAddClick(): void {
        const newRow = this.managePhonesPopupService.createRowControls('', false);
        this.rows.push(newRow);
      }
    
      public onDeleteClick(row: IPhoneRow): void {
        this.rows = this.rows.filter(r => r != row);
      }
    
      public onCloseClick(): void {
        this.close().then();
      }
    
      public onSubmitClick(): void {
        const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
        this._canSave = false; // Update the private property
    
        this.params
          .onSubmit(changes)
          .pipe(take(1))
          .subscribe(() => {
            this.close(true).then();
          });
      }
    
      private initRows(phones: IEmployeeCellphone[], emergencyPhone?: string): void {
        const rows: IPhoneRow[] = phones.map(p => this.managePhonesPopupService.cellphoneToRowControls(p));
    
        if (!!emergencyPhone) {
          rows.push(this.managePhonesPopupService.emergencyPhoneToRowControls(emergencyPhone));
        }
    
        this.rows = rows;
      }
    }

Answer №3

Within your code, the canSave function serves as a getter, meaning it is a read-only property. However, you are attempting to assign a value to it, which violates this constraint.

Instead of directly assigning a value to canSave, the recommended approach is to update the properties that influence the behavior of canSave. In this scenario, canSave relies on this.rows and this.params. Therefore, these properties should be modified within the onSubmitClick method.

Below is an example:

public onSubmitClick(): void {
 const changes = this.managePhonesPopupService.getChanges(this.rows, this.params);
 
 // Update the rows or params here
 // For instance, if you wish to mark all rows as invalid, you can accomplish this by:
 this.rows = this.rows.map(r => ({ ...r, phoneControl: { ...r.phoneControl, valid: false } }));

 this.params
   .onSubmit(changes)
   .pipe(take(1))
   .subscribe(() => {
     this.close(true).then();
   });
}

By updating this.rows to designate all rows as invalid, you will need to customize this section based on your specific requirements.

*The crucial step is to adjust the properties that impact canSave, rather than modifying canSave itself.

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

What is the best way to avoid looping through duplicate keys in a JSON using Javascript?

I have been struggling to find a solution to a basic question on my own, despite my attempts. I apologize in advance for my inability to find the answer. The issue I am facing is with a JSON object that contains multiple keys with the same name, for examp ...

What is the best way to continuously call an asynchronous method in native JavaScript until a successful response is received?

There is a scenario where I have an asynchronous method that can either return success or failure. The requirement is to repeatedly call this async method from another function until it returns success. However, if it fails consecutively for 5 times, the ...

What is the correct way to retrieve a JSON object instead of getting [Object object]?

Creating a basic web scraper integrated with mongoDB. Even though the API returns the JSON object in the correct format, when trying to append it to a bootstrap card on the page, I'm getting [Object object]. Below is my JavaScript code running on th ...

Looking for a solution to my issue - my for loop is looping more times than it should

I am designing a confirm dialog using jQuery and Bootstrap. When the user clicks on 'Yes' or 'No', it should trigger an action, such as drawing two squares each time. The first time I click either button, it draws 2 squares. However, wi ...

Enhance constructor functionality in Ionic 4 by incorporating additional parameters

Recently, I started using Ionic and came across a location page. In the location/location.page.ts file, there was an automatically generated empty constructor like this: constructor() { } Initially, the page functioned properly with this setup. However, ...

Modal does not close

I am experiencing an issue with closing a modal. I have checked jQuery and everything seems to be working fine. Currently, I am using version 1.12.4 and have the following script tag in the head of my code: <script src="https://ajax.googleapis.com/aja ...

Angular 2: Finding the total of an item in ngFor loop

I need help with calculating the total amount of items outside of an ngFor loop. HTML <div *ngFor="let item of items"> <input type="text" [(ngModel)]="item.price"> <input type="text" [(ngModel)]="item.quantity" (ngModelChange)=" ...

Prevent parent from scrolling when hovering over a div in HTML5

Unfortunately, the scrolling attribute is not supported in HTML5. I'm facing an issue where I have an svg inside an iframe within a div, and I need to enable scroll functionality within the div while preventing the page from scrolling at the same time ...

The "loose" mode is not resolving the issue with the lack of support for the experimental syntax 'classProperties' that is currently disabled

Error Message: The experimental syntax 'classProperties' is currently not enabled Even after trying the suggested solutions, I still encounter the error during re-building. Click here for more information on the experimental syntax 'classP ...

Utilize the NPM package manager in the zsh shell on Ubuntu within a Windows 10

After transitioning to the zsh for coding in Python and configuring the environment variables, I am now encountering an issue while trying to start a small JavaScript project. The problem arises when attempting to use npm, as initializing the repo results ...

Ways to retrieve every header from a response in Angular 2?

https://i.sstatic.net/1kagA.png The response headers I am observing in Chrome Dev tools differ from the ones displayed by Angular 2 in the Chrome console. https://i.sstatic.net/hgVtC.png After running the following code: this.http.get(tempUrl).map(res= ...

Navigating advanced search through nuanced filters dynamically with AngularJS

Here you will find the advanced search form: https://i.stack.imgur.com/g7Hiz.png I have successfully created a URL and parameters for document sections, but I am struggling to come up with a solution for managing the "Add Property Restrictions" section w ...

The error message "Unable to instantiate Jest, Enzyme, React, Next.js, Typescript .default" indicates that the default

I am trying to create a basic test to ensure that my next.js page loads correctly. I followed an informative tutorial, but I encountered an error related to the use of simple-react-validator when running tests using Jest: TypeError: simple_react_validat ...

Removing a particular value from a cookie using jquery

I'm currently in the process of creating a shopping cart system that allows users to add or remove products from their basket. For each product, I am storing two pieces of information in the product cookie: the product barcode and price. This is wha ...

Issue with PrimeReact dropdown component not recognizing an array in TypeScript

Trying to incorporate the PrimeReact Dropdown component in a NextJs app with TypeScript. Encountering an error when attempting to select options from the dropdown list: "Objects are not valid as a React child (found: object with keys {name, code})" The b ...

Leveraging useContext to alter the state of a React component

import { createContext, useState } from "react"; import React from "react"; import axios from "axios"; import { useContext } from "react"; import { useState } from "react"; import PermIdentityOutlinedIcon f ...

using a variable object to load, access data, and handle errors through mutations

element, I have incorporated two distinct mutations in a single react component: const [get_items, { error, loading, data }] = useMutation(GET_ITEMS); const [add_to_cart] = useMutation(ADD_TO_CART); To streamline and access both components' error, ...

How come Angular is reconstructing a child component instead of simply updating it when I assign a new value to an element in the parent array?

In my codebase, there is a parent component set up like this: @Component({ selector: 'parent-component', templateUrl: 'parent-component.html', }) export class ParentComponent { items : SomeClass[] = [....]; // Array filled w ...

Explore the jQuery feature that allows you to hover over text

I'm facing an issue that has got me a bit stuck on how to resolve it. Currently, when hovering over this specific image, the opacity decreases (exposing a background color) and text appears. However, I want this effect to persist even when hovering o ...

Adding the height of one element to another element's style value

Having a slight issue with my script. I am trying to retrieve the height of an element and use this value as the top position in CSS for another element. Here is my code snippet: var imageHeight = $('.photo_panel img').height(); $('.close_ ...