The object is given a value in the form of a string, even though it is a strongly-typed variable

I'm encountering something unusual in my code. In the following example, there is a (change) event that captures the current value selected by the user from a dropdown menu.

<div style="padding-right: 0; width: 100%;">
    <label style="width: 100%;">
      <select
        [(ngModel)]="courseContentButtonSelectedEvent"
        class="course-content-sidebar-form-control"
        (change)="setCourseContentButtonEventStep($event)"
      >
        <option
          *ngFor="let courseContentButtonEvent of courseContentButtonEventList"
          [value]="courseContentButtonEvent.id"
          [selected]="courseContentButtonEvent.id == courseContentButtonSelectedEvent"
          >{{ courseContentButtonEvent.value }}</option
        >
      </select>
    </label>
  </div>

The mentioned method is setCourseContentButtonEventStep.

  setCourseContentButtonEventStep(event: Event): void {
    const courseContentButtonEventType: CourseContentButtonEventType = ((event.target as HTMLInputElement)
      .value as unknown) as CourseContentButtonEventType;
    let courseContent = JSON.parse(JSON.stringify(this.courseContent));
    this.courseContent = CourseContentService.setCourseContentButtonEventStep(
      courseContent,
      courseContentButtonEventType,
      this.selectedCourseContentUid,
      this.selectedCourseElementUid,
      this.courseContentButtonEventIndex
    );
    this.store.dispatch(builderActions.setCourseContent({ courseContent: courseContent }));
  }

This method then invokes the setCourseContentButtonEventStep function within the CourseContentService.

  static setCourseContentButtonEventStep(
    courseContent: ICourseContent[],
    courseContentButtonEventType: CourseContentButtonEventType,
    selectedCourseContentUid: string,
    selectedCourseElementUid: string,
    courseContentButtonEventIndex: number
  ): ICourseContent[] {
    for (let i = 0; i < courseContent.length; i++) {
      if (courseContent[i].uid === selectedCourseContentUid) {
        for (let j = 0; j < courseContent[i].button.length; j++) {
          if (courseContent[i].button[j].uid === selectedCourseElementUid) {
            for (let k = 0; k < courseContent[i].button[j].event.length; k++) {
              if (k == courseContentButtonEventIndex) {
                courseContent[i].button[j].event[k].action = courseContentButtonEventType;
              }
            }
          }
        }
      }
    }
    return courseContent;
  }

Now interestingly, despite the casting of courseContentButtonEventType, it is being added to the object as a string instead of a number. For instance, inspect the data object below, under button -> event -> action, specifically

"action": "4"
:

[
  {
    "id": 1,
    "uid": "card-HJUI9b9Nre",
    "body": {
      "text": "Testing"
    },
    "type": 0,
    "button": [
      {
        "uid": "button-4WhgDe8mhe",
        "title": "Get Started",
        "event": [
          {
            "id": 1,
            "action": 5,
            "value": "https://en.wikipedia.org/wiki/Educational_technology"
          },
          {
            "id": 2,
            "action": "4"
          }
        ],
        "isEnabled": true
      }
    ],
    "audio": {
      "uid": "audio-NIiH1fCkqd",
      "url": "https://s3.eu-west-2.amazonaws.com/media.example.co.uk/default/testing_startup_ideas.mp3"
    }
  }
]

Answer №1

If you want to tidy up your code, consider using ngValue instead of value.

<select
[(ngModel)]="courseContentButtonSelectedEvent"
class="course-content-sidebar-form-control"
(ngModelChange)="setCourseContentButtonEventStep($event)"
>
    <option
      *ngFor="let courseContentButtonEvent of courseContentButtonEventList"
      [ngValue]="courseContentButtonEvent"
      [selected]="courseContentButtonEvent.id == courseContentButtonSelectedEvent"
      >{{ courseContentButtonEvent.value }}</option
    >
</select>

By using ngValue instead of value, you can store an object instead of a string.

Also, pay attention to the difference between (change) and (ngModelChange).

setCourseContentButtonEventStep(courseContentButtonEventType: CourseContentButtonEventType): void {
    let courseContent = JSON.parse(JSON.stringify(this.courseContent));
    this.courseContent = CourseContentService.setCourseContentButtonEventStep(
      courseContent,
      courseContentButtonEventType,
      this.selectedCourseContentUid,
      this.selectedCourseElementUid,
      this.courseContentButtonEventIndex
    );
    this.store.dispatch(builderActions.setCourseContent({ courseContent: courseContent }));
}

This refactoring will greatly improve the readability of your event handling logic.

One more thing to note is the type in your event handler, "CourseContentButtonEventType". Is this intentional? Does it match the items in your list?

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

Troubleshooting the error message "Encountering issues with Module build failed (from ./node_modules/postcss-loader/src/index.js)"

Running ng serve results in compilation failure after the chunks are generated. The same codebase is functioning on a co-worker's computer with identical versions as listed below: Node version: 10.16.3 NPM version: 6.9.0 @angular/cli: 7.3.9 Tried ...

The problem arises when trying to use the Jquery click event on buttons that have been generated

I've encountered an issue where I can create components dynamically, but the click event doesn't seem to work on buttons that are dynamically generated. Check out the code snippet below: HTML file: <div class="merge_sections">&l ...

What is the best way to save the data received from createApi into the Redux store?

Currently, I am faced with the challenge of storing user data (such as name, email, etc.) obtained through the createApi function into Redux store. However, I'm unsure of the best practice to achieve this. In my userApi.js file: export const userApi ...

Implement the TypeScript handleChange function for input fields and dropdown menus

Currently, I am in the process of developing a form using TypeScript and Material-UI components. My objective is to create a change handler function that can be utilized for both select and textfield changes. Below are my state and functions: const [re ...

jQuery code unable to alter the class of a div

Need help with a script on my single page site that adds a "read more" style link to a content area's div. The goal is for the button to change the class of the content area when clicked, showing all of the content. Clicking again should hide the cont ...

Utilizing Electron's <webview> feature to display push notification count in the title

I'm currently working on a Windows app using Electron's webViewTag to integrate WhatsApp Web. While I have successfully implemented desktop toast notifications, I am curious if it is possible to display a notification count in the title bar of my ...

Navigating through the complexities of managing asynchronous props and state in React-components

I'm really struggling to understand this concept. My current challenge involves passing asynchronously fetched data as props. The issue is that the props themselves are also asynchronous. Below is a simplified version of the component in question: i ...

The terminal in VS CODE is not able to detect Stripe

When I attempt to run the command 'stripe listen' in the VS Code terminal, an error is thrown: The term 'stripe' is not recognized as the name of a cmdlet, function, script file, or operable program. Please check the spelling of the ...

Function that observes with the pipe syntax

Is it possible to apply map, switchMap, or any other operator in conjunction with a function that outputs an observable? The objective here is to transform the result of the observable function and utilize that value during the subscription to another ob ...

Tips for defining a function across a Angular project

I have the following configuration set up in an Angular5 project using Angular-cli 1.5 within typings.d.ts declare interface String { toSentenceCase(): string; } declare function _debug(o, message?, type?): void; inside app/core/common.ts String.pro ...

Issues related to .maps and the use of import 'rxjs/add/operator/map';

Having an issue with Angular 4 and rxjs/add/operator/map. Even after importing rxjs/add/operator/map, I am unable to use .map. Visual Basics keeps displaying two error messages: message: 'Declaration or statement expected.' message: 'Cannot ...

Tips for dynamically altering the data type of an object in Angular depending on a certain condition

I'm currently in the process of developing an online store and facing challenges with integrating a dynamic form system that can adapt based on the type of product being added to the store. For instance, if I select the 'Clothing' category, ...

What is the best way to specify the data type of a value within a map in TypeScript?

I need assistance defining the value of a key in a map as a key-value pair in TypeScript. map: { key: someStruct } Is it possible to declare the type of someStruct and initialize it simultaneously? What is the best approach for accomplishing this? ...

Angular 2 has its own version of $q.when called RxJs

Back in the AngularJS 1.* days, I used to have this code snippet to refresh the auth-token: ... if (!refreshTokenInProgress) { refreshTokenInProgress = AuthService.refreshToken(); } $q.when(refreshTokenInProgress, function () { refreshTokenInProgre ...

What methods can be used to identify the presence of a scrollbar in an

Currently, I am facing an issue with my SAPUI5 app. In the app, I have a table that extends beyond the screen. To allow users to navigate back to the top of the table, I have added a button. However, I only want this button to be displayed when the table g ...

Tic-Tac-Toe: The square's value stays unchangeable

Currently, I am working on creating a tic-tac-toe game using pure vanilla Javascript, so I am aiming to keep it as simple as possible. I have run into an issue and need some guidance. The main requirement is that once a square has been clicked and filled ...

The formatting directive fails to keep pace with speedy input

I am working on a feature to automatically format the input field as the user types, transforming the letters into valid initials in uppercase with dots in between. The formatting needs to happen in real-time as the user inputs characters, rather than aft ...

What is the best method for selecting or deselecting all checkboxes except for one using a single checkbox in angularjs

$scope.checkAll = function() { if ($scope.selectedAll) { $scope.selectedAll = true; } else { $scope.selectedAll = false; } angular.forEach($scope.MyProducts, function(item) { item.Selected = $scope.selectedAll; }); /*});*/ } <di ...

Creating a Dynamic Login Panel Using HTML, CSS, and Jquery

Designing a dynamic sliding login panel utilizing Html, CSS, and jquery alongside various plugins. Check it out here: http://24.125.42.135/ When activated, the bar smoothly pushes down the content (click on the login option at the top right corner). This ...

Is there a way to extract the text from the inner div of an element using nightwatch.js?

I'm attempting to retrieve the content of a cell within a table, with the following CSS structure: <div data-testid="cellvalue_row-1_col-0" class="Table-cellContent" xpath="1"><span data-testid="tableCellCon ...