When assigning JSON to a class object, the local functions within the class became damaged

This is a demonstration of Object Oriented Programming in JavaScript where we have a parent Class called Book with a child class named PriceDetails.

export class Book {
  name: String;
  author: String;
  series: String;
  priceDetails: Array<Price>;
}

// This is the child class

export class Price {
    price1: Number; 
    price2: Number;
    price3: Number;
    price4: Number;
    price5: Number;
    price6: Number;
    price7: Number; 
    public setPrice(columnNumber:number, newPrice:number) {     
        this["price"+ columnNumber] = newPrice;  
    }   
}

We are fetching data from an API endpoint:

this.http.get(this.booksUrl)
  .subscribe(res => console.log(res));

The JSON response received looks like this:

{
    "name": "Apple",
    "author": "Shaik",
    "series": "Classic",
    "priceDetails": [
                    {
                        "price1": 1, 
                        "price2": 2, 
                        "price3": 3, 
                        "price4": 4, 
                        "price5": 7, 
                        "price6": 10, 
                        "price7": 8, 
                      },
                      {
                        "price1": 11, 
                        "price2": 22, 
                        "price3": 23, 
                        "price4": 34, 
                        "price5": 37, 
                        "price6": 10, 
                        "price7": 38, 
                      }, 
                      {
                        "price1": 31, 
                        "price2": 33, 
                        "price3": 24, 
                        "price4": 34, 
                        "price5": 37, 
                        "price6": 10, 
                        "price7": 38, 
                      }
                ],
}

However, when trying to call a local function after receiving the JSON data, an error occurs:

this.Book.priceDetails[0].setobj(1, 15)

The error message states - core.js:12301 ERROR Error: Uncaught (in promise): TypeError: this.Book.priceDetails[0].setobj is not a function

Answer №1

When dealing with JSON data from the server, it is important to note that the output of JSON.parse method will always be an array, object, number, or string unless a reviver parameter is specified. This means that the result will not be an instance of your custom classes like Book or price.

To address this issue, you can create copy constructors for your classes and pass the received values to them. For example:

export class price
{
    constructor(source: price){
      this.price1 = source.price1;
      this.price2 = source.price2;
      this.price3 = source.price3;
      this.price4 = source.price4;
      this.price5 = source.price5;
      this.price6 = source.price6;
      this.price7 = source.price7;
    }
    price1: Number; 
    price2: Number;
    price3: Number;
    price4: Number;
    price5: Number;
    price6: Number;
    price7: Number; 
    public setPrice( lcol:number,lnprice:number)
    {     
        this["price"+ lcol]=  lnprice;  
    }
}

and

export class Book
{
    constructor(source: price){
      this.name= source.name;
      this.author= source.author;
      this.series= source.series;
      this.priceDetails= source.priceDetails && source.priceDetails.map(a=>new price(a));
    }
  name: String;
  author: String;
  series: String;

  priceDetails: Array<price>;

}

You can then use these classes like so:

this.http.get(this.booksUrl).pipe(map(a => new Book(a))).subscribe(res => console.log(res));

Answer №2

It appears that the setobj() method may not be present in the class price since only setPrice() is visible. Another possibility is that during retrieval of book data from the http request, you might be overwriting your pricedetails array with a simpler object structure, lacking the setobj() function:

{
  "price1": Number, 
  "price2": Number, 
  "price3": Number, 
  "price4": Number, 
  "price5": Number, 
  "price6": Number, 
  "price7": Number, 
  public setobj();
}

This could potentially result in losing access to the setobj() method which seems crucial for managing price objects.

If this is indeed the issue, consider using constructors as a solution and ensure to check and maintain the integrity of your data structures throughout the process.

Additionally, providing more code snippets for review would greatly assist in identifying potential solutions or modifications needed for resolving this issue effectively.

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

Personalized Jasmine matchers for a Protractor/WebDriverJS component

Greetings fellow developers, I'm looking to create a custom matcher for Protractor/WebDriverJS element. Can anyone assist in improving my current code? Here is what I aim to include in the specs files: var button = element(by.tagName('button&a ...

Format the date using the Datepicker

I am looking to update the date format in my date picker from "12/25/2022" (for example) to "25/December/2022" Here is the code I have: $(".date-picker").datepicker({ format: 'dd-mm-yyyy', minDate: 0, numberOfMonths: \[3,1&b ...

When useEffects are linked in such a way that the first one updates a dependency of the second, it can lead to

Modified code block with console logs integrated from approved solution. I have stripped down a search bar component to its simplest form: import React, { useEffect, useRef, useState } from "react"; import axios from "axios"; const re ...

What is the best way to send a promise back from my service to my controller?

While I have posed this question in various forms, I now find myself stuck with a piece of code that contains an elusive bug. My Angular service looks like this: .service("lookupDataService", [ '$q', '$http', '$timeout&ap ...

The element.find() function is experiencing issues when utilizing a templateUrl within a directive

My aim is to apply focus on an input field using a custom directive within a form. Initially, everything was functioning correctly when utilizing the template property in the directive. However, upon transferring the template into a separate HTML file usin ...

Trouble with toggling div visibility using jQuery and AJAX

I'm trying to display a specific div based on the result of an SQL query. The problem I'm facing is that I can't seem to toggle the divs asynchronously. Currently, the page needs to be reloaded for the div to reflect the changes. <?ph ...

I'm having trouble asynchronously adding a row to a table using the @angular/material:table schematic

Having trouble asynchronously adding rows using the @angular/material:table schematic. Despite calling this.table.renderRows(), the new rows are not displayed correctly. The "works" part is added to the table, reflecting in the paginator, but the asynchron ...

Unexpected behavior: Angular4/Javascript Date object alters when timezone is specified in Date constructor

In my Angular 4 application, I encountered an issue with a date retrieved from an API call. The date is in the format '1990-03-31T23:00:00-06:00' and when attempting to create a Date object and retrieve the month using getMonth(), it returns the ...

Error: Unable to simplify version range

Attempting to follow the Express beginner's guide. I created an app and executed npm install as per the provided instructions. > npx express-generator --view=pug myapp > npm install npm ERR! semver.simplifyRange is not a function npm ERR! A com ...

Using the Gmail API to retrieve the access token details by extracting the "code" parameter from the URL of a pop-up window

I am currently in the process of authenticating Gmail using OAuth2 for my web application. Upon receiving a URL from the server, the client opens a pop-up window with the following code: var win = window.open(data.google_oauth_url, `<h1>Gmail ...

Refresh all tabs in the TabContainer

I have implemented multiple tabs using dojo on a web page, and I need to refresh the current tab every 5 seconds without refreshing the entire page. You can check out the code in this fiddle: http://jsfiddle.net/5yn2hLv9/4/. Here is an example of the code ...

Having difficulties with Vue components displaying in Laravel's blade.php file

Let me share my current setup with you: This is the main "Welcome.blade.php" file where I have included relevant information as the file is quite lengthy: <div id='app'> <router-view></router-view> </div> <script src ...

Error detected in JSON syntax... Where is it hiding?

After running the code through jsonlint, it flagged an error on line 17. However, upon close inspection of the file which contains about 1000 lines, I couldn't pinpoint the issue. It's possible that the problem lies further down the file, but I w ...

What is the best way to determine the total of values from user-input fields that are created dynamically

Scenario- A scenario where a parent component is able to create and delete input fields (child components) within an app by clicking buttons. The value of each input field is captured using v-model. Issue- The problem arises when a new input field is crea ...

Retrieving information in JSON format

My goal is to retrieve data from the info.php file in order to utilize it in my project. This is what the content of info.php looks like: <?php $dbh = new PDO('mysql:host=localhost;dbname=csgo', 'root', ''); $sth = $dbh ...

Guide to dynamically setting SCSS $variables in JavaScript after retrieving them from local storage in a React application

In my current situation, I am retrieving color combinations in hash values from the database through an API call and then saving them in localStorage for future use. However, I am facing a challenge when trying to access this data from localStorage and uti ...

Obtaining a file using capybara independently of rails

Case Study: Attempting to access an external URL using Capybara for downloading a file. It is necessary to use Selenium or Webkit as the driver, since Rack-test does not allow visiting external URLs. This website utilizes iframes. The prompt for file dow ...

Stop music with one click, code in Javascript

I am encountering an issue with a set of 5 div boxes on my website. Each box is supposed to play a specific audio track when clicked, based on data attributes. However, I'm having trouble pausing the previous track when clicking on a new box, resultin ...

The Vue event was triggered, however there was no response

My current project consists of a Typescript + Vue application with one parent object and one component, which is the pager: //pager.ts @Component({ name: "pager", template: require("text!./pager.html") }) export default class Pager extends Vue { ...

Generate new variables based on the data received from an ajax call

Suppose there is a .txt file containing some integers separated by spaces, like '22 1 3 49'. I would like to use Ajax to read the file as an array or list, and then save each integer as a JavaScript variable. Currently, this code reads all cont ...