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

Scraping the Web with Python: Harnessing the Power of Selenium and

Seeking assistance with a problem I've encountered. I'm attempting to extract numbers from a specific website (link provided in the code below). Since the website utilizes JavaScript, my approach involves using selenium to load the page first and ...

Sinon causing 'unsafe-eval' error in Chrome extension unit tests

Recently, I've been conducting unit tests on my Chrome extension using Mocha, Chai, and Sinon. However, I encountered an issue when attempting to stub an object from a method: EvalError: Refused to evaluate a string as JavaScript because 'unsafe ...

Limit the selection of 'pickable' attributes following selections in the picking function (TypeScript)

In the codebase I'm working on, I recently added a useful util function: const pick = <T extends object, P extends keyof T, R = Pick<T,P>>( obj: T, keys: P[] ): R => { if (!obj) return {} as R return keys.reduce((acc, key) => { re ...

Steps to develop a collaborative NPM package

I am currently in the process of developing an NPM package using Typescript that contains solely my type interfaces. At the moment, my project has the following folder structure: project │ index.ts │ └───types │ restaurant.ts │ ...

How come the back button does not initiate client-side navigation in a Next.js application?

In my Next.js application utilizing GraphQL to fetch articles from a server, I encountered an issue with dynamic routing when reloading the page while on an article and attempting to navigate back. The usual scenario works as expected: Index -> [slu ...

Create dynamic transitions for hidden elements using a special technique

Is it possible to smoothly transition a div element from display:none to display:block? I attempted to first set the display to block and then apply a transition, but it doesn't seem to be working as expected. HTML <input type="text" class="inp"& ...

JQuery .click function functioning properly on alternate clicks

Currently, I am integrating JQuery with ReactJS. However, there seems to be an issue where the action that should occur when clicking a button only works on every other click. The first click doesn't trigger anything, but the second one does. I attem ...

Unlock the power of jQuery chaining with the val() method

My selected background color is set to: var _back = "#FF0000"; Why doesn't this code change the input field's background color: $("#input").val( _back ).css("background-color",$(this).val()); But this one does? $("#input").val( _back ) ...

transfer properties to a dynamic sub element

I am currently working on a multi-step form project. I have successfully implemented the form so that each step displays the corresponding form dynamically. However, I am facing challenges in passing props to these components in order to preserve the state ...

Having trouble with the Cordova button not functioning on Android 9? A beginner seeks assistance

I attempted to create a button with the id of "clickme" that links to index.html and js/buttonexample.js. Although I could see the button on both the browser and android emulator, it wasn't functioning as expected when clicked. js/buttonexample.js d ...

How can CSS positioning be utilized to align lines accurately?

Recently, I created a basic jsbin to draw a line connecting two points. It doesn't rely on any drawing libraries; just plain JavaScript and jQuery. I managed to calculate the angle using code I found in this library. When dragging the circle at the ...

'Android users experiencing issue with custom marker icons failing to display'

I have the following code snippet: this.service.getListe(data).forEach((data: any) => { const marker: Marker = this.map.addMarkerSync(data); marker.on(GoogleMapsEvent.MARKER_CLICK).subscribe((params) => { this.click(params); }); ...

Calling gtag("event") from an API route in NextJS

Is there a way to log an event on Google Analytics when an API route is accessed? Currently, my gtag implementation looks like this: export const logEvent = ({ action, category, label, value }: LogEventProps) => { (window as any).gtag("event&quo ...

The Vimeo player JavaScript API is experiencing issues on iOS devices

I am facing an issue where the API for playing a video only works on iOS after the play button is clicked in the player. However, it works fine on desktop and Chrome for Android. http://codepen.io/bdougherty/pen/JgDfm $(function() { var iframe = $(&a ...

When in production mode, parameter routing and conditions do not function as expected

I have a straightforward routing setup like the following: import { NgModule } from '@angular/core'; import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: 'scenario', ...

Utilizing Typescript/React to Invoke Microsoft Graph Function and Validate M365 Group Owners

As a newcomer to React and TypeScript, I am eager to utilize the Microsoft Graph API in my React/TypeScript application to verify if the logged-in user is an owner of an M365 group. This is the code snippet I currently have: import { callMsGraph } from ...

Displaying the quantity of directories within a specific location

Can anyone help me troubleshoot my code? I'm trying to have a message displayed in the console when the bot is activated, showing the number of servers it is currently in. const serversFolders = readdirSync(dirServers) const serversCount = parseInt(s ...

Looking to duplicate the elements with the click of a button?

I am in need of assistance with my registration form. My goal is to move the elements contained within the <fieldset> tags to the end of a row when the user clicks the + button. The result you see initially has been recreated. Thank you for your s ...

The ref.on() method fails to trigger a response from a function, despite producing the intended outcome

I've been working on developing an app called workspace. I previously asked a question, but I've made more additions to the features now. One of the new features is a remarks system. After experimenting with different versions of my code, the ver ...

Having trouble replacing scss variables in react-h5-audio-player

I recently integrated react-h5-audio-player into my project and followed the instructions on the README page to customize the styles by updating the SCSS variables that control the colors. However, it appears that my custom styles are not being applied. An ...