Displaying properties of a class in Typescript using a default getter: Simplified guide

Here is an interface and a class that I am working with:

export interface ISample {
  propA: string;
  propB: string;
}

export class Sample {
  
  private props = {} as ISample;

  public get propA(): string {
    return this.props.propA;
  }

  public set propA(propA: string) {
    this.props.propA = propA;
  }

  public get propB(): string {
    return this.props.propB;
  }

  public set propB(propB: string) {
    this.props.propB = propB;
  }

}

When initializing the object using the class, I do it like this.

let sample = new Sample();
sample.propA = 'A';
sample.propB = 'B';

However, when I attempt to print the object using console.log(sample), the output is:

props: {propsA: "A", propsB: "B"}
propsA: (...)
propsB: (...)

My question is, how can I modify the output so that it only shows

{propsA: "A", propsB: "B"}
when using console.log(sample)?

Note: The versions I am using are typescript 3.8.3 and Angular 9.

Answer №1

If you want to access the properties directly without using any class object instances in between, you have the option to bypass the Sample class completely. Instead, consider utilizing the ISample interface directly.

You can give this a try:

export interface ISample {
  propA: string;
  propB: string;
}

export class AppComponent  {
  sample = {} as ISample;

  ngOnInit() {
    this.sample.propA = 'A';
    this.sample.propB = 'B';

    // Output will be {propA: "A", propB: "B"}
    console.log(this.sample);
  }
}

Answer №2

Your Sample category includes a property named sample that derives from the ISample interface. Therefore, it is evident that you are retrieving the log of

props: { propA: "A", propB: "B"}
.

In order for propA and propB to be direct elements of your category, you must properly inherit the Interface. By doing so, you will need to establish propA and propB as direct elements of Sample which will result in the desired log.

export class Sample implements ISample {
  propsA = '';
  propsB = '';
}

Remember to adjust your setters and getters accordingly when utilizing private states.

Answer №3

If you want to customize the output of an object, you can override the toString() method:

export interface IData {
  name: string;
  value: number;
}

export class CustomData {
  
  data = {} as IData;

  public get name(): string {
    return this.data.name;
  }

  public set name(name: string) {
    this.data.name = name;
  }

  public get value(): number {
    return this.data.value;
  }

  public set value(value: number) {
    this.data.value = value;
  }

  toString() {
    return this.data;
  }
}

let customData = new CustomData();
customData.name = 'John';
customData.value = 42;

console.log(customData.data)

Answer №4

When it comes to changing the display of a class using console.log, there are very limited options available. The function is built into the browser and doesn't offer much flexibility for customization. For example, you can refer to the implementation in Firefox (FF implementation).

function log(aThing) {
  if (aThing === null) {
    return "null\n";
  }

  // Code continues...

In instances involving classes (

typeof aThing == "object"
), the function calls Object.getOwnPropertyNames to display all properties.

It's important to note that using toString won't be effective for objects with

typeof aThing == "object"
.

A similar implementation can be seen in Chrome's V8ValueStringBuilder.append:

// Code snippet from V8
if (value->IsObject() && !value->IsDate() && !value->IsFunction() &&
        !value->IsNativeError() && !value->IsRegExp()) {
    v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
    v8::Local<v8::String> stringValue;
    if (object->ObjectProtoToString(m_context).ToLocal(&stringValue))
        return append(stringValue);
}
// Another code snippet from V8
V8_WARN_UNUSED_RESULT MaybeLocal<String> ObjectProtoToString(
     Local<Context> context);

For further information, you can visit: Does console.log invokes toString method of an object?

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

Tips for customizing the cursor to avoid it reverting to the conventional scroll cursor when using the middle click

When you wish to navigate by scrolling with the middle mouse button instead of using the scroll wheel, simply middle-click and your cursor will change allowing for easy scrolling on web pages. Even though I am utilizing style="cursor: pointer" and @click. ...

The NGXS state does not get updated when a lazy loaded component is used

Recently, I started experimenting with the new lazy loaded components in Angular 9. I have a stateful component using NGXS with its state being lazy loaded in a module close to the component. However, after the component renders, the store does not update ...

Unable to locate the required conditional template for the 'mdRadioButton' directive due to the absence of the 'mdRadioGroup' controller

I am currently working on developing a custom directive that will help me display questions within a survey. Given the multiple types of questions I have, I decided to create a single directive and dynamically change its template based on the type of quest ...

The type definition file for 'jest' cannot be located, despite the fact that jest has been successfully installed

SOLUTION STRATEGY: If you encounter a similar issue and are looking for a more comprehensive solution rather than quick fixes, consider recreating the repository. While it involves more effort initially, it can prevent future issues. In my case, the repos ...

Steps for changing the language in KeyboardDatePicker material ui

Currently, I am utilizing material ui on my website and leveraging the KeyboardDatePicker API with successful results. The only issue is that the months' names and button text are displayed in English, whereas I would prefer them to be in Spanish. Des ...

NextJS Router delays data reloading until page receives focus

Struggling with creating an indexing page in NextJS. Attempting to retrieve the page number using the router: let router = useRouter() let page = isNaN(router.query.page) ? 1 : parseInt(router.query.page); This code is part of a React Query function withi ...

Puppeteer has a limit of running only three instances on Heroku

Currently, I am in the process of developing a website that employs puppeteer to extract information from another site. The npm server works flawlessly on my local machine, but once deployed on Heroku, it halts after processing the first three files. The ...

Dimensions of Doughnut Chart in Chart.js

In my Angular project, I currently have two versions. The old production version uses an outdated version of ng2-charts, while I am working on upgrading it. Interestingly, I noticed a strange difference when using the doughnut chart from ng2-charts. When ...

Sort through a list of objects using the criteria from a separate array

Looking to apply a filter on an array of objects: const myArray = [{ id: 4, filters: ["Norway", "Sweden"] }, { id: 2, filters :["Norway", "Sweden"] }, { id: 3, filters:["Denmark", "Sweden&q ...

Vue.js has encountered a situation where the maximum call stack size has been exceeded

I have implemented a method called cartTotal that calculates the total price of my products along with any discounts applied, and I am trying to obtain the final value by subtracting the discount from the total. cartTotal() { var total = 0; var di ...

Revise the form used to edit data stored in Vuex and accessed through computed properties

My form component is used for client registration and editing purposes. Upon creation of the form component, I check if there is an ID in the URL to determine which type of form to display. If no ID is present (indicating a new client registration), all fi ...

Creating keys from extensive JSON data without having to manually match types using Typescript

Is there a way to efficiently parse and access the values in large JSON files using Typescript, without the need to manually define interfaces for all expected key/value pairs? In the past, working with small JSON files required only extracting a few spec ...

What do I do when I get a "findByIdAndUpdate is not a function" error from my controller after requiring the model

I am currently developing a web application for my company that allows us to access and manage a database of customers and their information using MongoDB, Mongoose, and Express. Our company specializes in reselling used copiers/printers and offering maint ...

The appearance of the circle in Safari is rough and lacks smoothness

My circle animation works perfectly on Google Chrome, but when I switch to Safari the edges appear faded and blurry. I tried adding "webkit" to fix it, but had no luck. Is there a compatibility issue with Safari and CSS animations? Here is my code: Snapsh ...

Modify the background of a Div element by selecting an alternate color palette

Here is my code that changes the background of a Div on select change from a dropdown. I believe there might be a more efficient way to achieve this. Can anyone provide recommendations? Thank you for taking a look. $(document).ready(function() { $(" ...

Scrolling to an id within dynamically loaded content using jQuery after an ajax request

After loading content via ajax, I am unable to scroll to the item, as the page remains at the top. Strangely, when I refresh the page dynamically with content caching enabled, the page scrolls to the desired target. var startPageLoader = function( pid, si ...

Testing in Jasmine: Verifying if ngModelChange triggers the function or not

While running unit tests for my Angular app, I encountered an issue with spying on a function that is called upon ngModelChange. I am testing the logic inside this function but my test fails to spy on whether it has been called or not! component.spec.js ...

What is the purpose of running "npm install" if the "node_modules" directory already exists?

When "npm install" is run on a project directory containing both a "package.json" file and a "node_modules" directory, what impact does it have? Does it replace the current modules with newer versions? Does it update them, or does it have no effect at all ...

Configure your restify REST API server to handle both HTTPS and HTTP protocols

I'm currently utilizing node.js restify version 4.0.3 The code snippet below functions as a basic REST API server supporting HTTP requests. An example of an API call is var restify = require('restify'); var server = restify.createServer( ...

Propagating numerical values through iterative iterations

I am currently facing an issue with passing values as props to a component using the forEach method in JavaScript. In addition to passing the existing values from an array, I also want to send another value that needs to be incremented by 1 for each iterat ...