Accessing attributes of a parent class object from within a child object

Imagine having four tabs within an Angular component, each with its own set of criteria for being displayed. Here's a high-level overview of the scenario.

export class DisplayTabs {
  foo: true;
  bar: false;
  tabs: {
    'A': { order: 1, get isVisible() { return this.foo; } },
    'B': { order: 2, get isVisible() { return !this.bar; } },
    'C': { order: 3, get isVisible() { return this.foo && this.bar; } },
    'D': { order: 4, get isVisible() { return !this.foo || this.bar; } }
  };
};

The current setup encounters an issue where this points to the tabs object rather than the encompassing DisplayTabs object. However, the decision on displaying the tabs relies on the properties of the DisplayTabs object itself.

I have considered structuring my tabs in a more organized and maintainable manner by defining them directly inside the DisplayTabs as follows:

export class DisplayTabs {
  foo: true;
  bar: false;
  get isTabAVisible() { return this.foo; }
  get isTabBVisible() { return !this.bar; }
  // etc.

Is there a way to reorganize this structure to achieve the desired outcome?

Answer №1

When faced with a situation where the natural approach clashes with the programming paradigm, it is crucial to reassess whether the correct paradigm is being used. In such cases, either the approach should be modified to align with the paradigm, or a different paradigm that complements the approach should be chosen. Consider this alternative solution:

type TabState = {
  foo: boolean
  bar: boolean
}

const state: TabState = {
  foo: true,
  bar: false,
}

enum TabOrder {
  A,
  B,
  C,
  D,
}

type Tab = {
  order: TabOrder
}

const isVisible = ({ foo, bar }: TabState, tab: Tab): boolean => {
  switch (tab.order) {
    case TabOrder.A: return foo;
    case TabOrder.B: return bar;
    case TabOrder.C: return foo && bar;
    case TabOrder.D: return !foo || bar;
  }
}

Playground

This approach is simpler to test (being a pure function dependent only on its arguments), well-typed, easier to debug, and so forth. While conventional wisdom may suggest that object-oriented programming is ideal for UI tasks, it's important to recognize that this isn't always the best fit. Even if you're constrained by an OO-centric framework or existing codebase, you can still encapsulate this functionality as a static method within a class.

Answer №2

At the beginning, you're defining a class but then switching to an object literal syntax. This can cause confusion as a class is not an object but rather a set of instructions for creating an object.

If we correct the syntax of your initial snippet, it will appear like this:

export class View {
    foo = true
    bar = false
    tabs = {
      'A': { order: 1, get isVisible() { return this.foo; } },
      'B': { order: 2, get isVisible() { return !this.bar; } },
      'C': { order: 3, get isVisible() { return this.foo && this.bar; } },
      'D': { order: 4, get isVisible() { return !this.foo || this.bar; } }
    }
  };

After making that correction, we can then implement an explicit constructor to access the object being constructed and use it within the methods:

export class View {
    foo = true
    bar = false
    tabs

    constructor() {
      const _this = this;
      this.tabs = {
        'A': { order: 1, get isVisible() { return _this.foo; } },
        'B': { order: 2, get isVisible() { return !_this.bar; } },
        'C': { order: 3, get isVisible() { return _this.foo && _this.bar; } },
        'D': { order: 4, get isVisible() { return !_this.foo || _this.bar; } }
      }
    }
  };

By creating an object instance with new View(), the methods within the tabs field will refer to the properties of the newly created 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

Ensuring the type of a specific key in an object

Seeking a more stringent approach regarding object keys in TypeScript. type UnionType = '1' | '2' | '3' type TypeGuardedObject = { [key in UnionType]: number } const exampleObject: TypeGuardedObject = { '1': 1, ...

Incorporate Select2 functionality within the Angular2 application

I'm currently working on incorporating the Select2 plugin into my Angular2 application. Successfully, I have managed to set up select2 and transform my multiple select fields as expected. However, I am now facing a challenge in retrieving the selected ...

Eliminate any repeated elements in the array by utilizing TypeScript

Hey, I'm trying to figure out how to remove duplicate entries from an array where the UserId values are the same, and keep only one of each unique entry. Can anyone help me with this? For example: a=[ {userId:1,name:''}, {userId:2,name:&apo ...

Ways to eliminate the white background gap between pages on ionic

While developing an app using Ionic, I encountered a strange issue. Everything runs smoothly on a browser, but when testing the app on an Android 5 device, I noticed a white background appearing between pages. The app loads correctly with the custom splas ...

TS2322 error: Attempting to assign type 'any' to type 'never' is invalid

Currently, I am utilizing "typescript"- "3.8.3", and "mongoose": "5.9.11". Previously, my code was functional with version "typescript": "3.4.x", and "mongoose": "4.x". Here is a snippet of my code: https://i.stack.imgur.com/j3Ko2.png The definition for ...

Generate an interactive sitemap.xml in ReactJS for each request made to http://example.com/sitemap.xml

I am working on a single-page application (SPA) using reactjs, and I have links in the format of http://example.com/blog/:id. I want to dynamically generate a sitemap for this site. While I'm aware that there are npm packages like react-router-sitema ...

Error: JSON unexpected token ' at position 2 - Solution for fixing this issue

Encountering a recurring JSON error where the user input from a textbox is being passed in JSON for assigning class level permissions in a parse server. var cc = "role:" + user; var jsonParam = "{ 'classLevelPermissions' : { ...

What is the correct way to add type annotations to an Axios request?

I have meticulously added type annotations to all endpoints in my API using the openapi-typescript package. Now, I am looking to apply these annotations to my Axios requests as well. Here is a snippet of code from a Vue.js project I have been developing: ...

Using Lodash to Substitute a Value in an Array of Objects

Looking to update the values in an array of objects, specifically the created_at field with months like 'jan', 'Feb', etc.? One way is to loop through using map as demonstrated below. However, I'm curious if there's a more co ...

Encountering an issue with Next.js, Typescript, and mongoose when attempting to use `let cached = global.mongoose

I attempted to create a cached mongoose connection for my Next.js + Typescript application, but the code I used was: let cached = global.mongoose; if (!cached) { cached = global.mongoose = { conn: null, promise: null }; } The use of global.mongoose res ...

"The list of table rows in a React application using Typescript is not rendering properly

I am encountering an issue where the rows in my table are not being rendered while trying to map objects from a list called items. I am working with typescript and react-bootstrap. Can someone help me understand why this is happening and how to resolve it? ...

Certain Material-UI components appear to lack proper styling

I found a tutorial on how to incorporate material UI into my app at this link: https://mui.com/material-ui/getting-started However, I noticed that some components are not styled as expected and customizing the theme seems to have no effect... This is how ...

Is it possible to implement drag and drop functionality for uploading .ply, .stl, and .obj files in an angular application?

One problem I'm facing is uploading 3D models in angular, specifically files with the extensions .ply, .stl, and .obj. The ng2-upload plugin I'm currently using for drag'n'drop doesn't support these file types. When I upload a file ...

Exploring Typescript for Efficient Data Fetching

My main objective is to develop an application that can retrieve relevant data from a mySQL database, parse it properly, and display it on the page. To achieve this, I am leveraging Typescript and React. Here is a breakdown of the issue with the code: I h ...

Sporadic UnhandledPromiseRejectionWarning surfacing while utilizing sinon

Upon inspection, it appears that the objects failApiClient and explicitFailApiClient should be of the same type. When logging them, they seem to have identical outputs: console.log(failApiClient) // { getObjects: [Function: getObjects] } console.log(expli ...

The variable 'data' is not a property of the type 'any[]'

I am currently facing an issue with a dummy service I created to fetch dummy data. When calling this service from a component ts file, I encountered the following error. After searching through some similar posts, I still haven't been able to resolve ...

insert information into a fixed-size array using JavaScript

I am attempting to use array.push within a for loop in my TypeScript code: var rows = [ { id: '1', category: 'Snow', value: 'Jon', cheapSource: '35', cheapPrice: '35', amazonSource ...

Can PassportLocalDocument and PaginateModel coexist within the same framework?

I am new to TypeScript and NestJS, looking to implement a pagination feature for all models in my application. Currently using NestJS with Mongoose for the API project. Here is an example of the user schema: export const UserSchema = new mongoose.Schema( ...

Encountering a TS2307 error while trying to import external modules into a TypeScript file

I recently added a new module using npm and now I'm trying to use it in my typescript file. npm install marker-animate-unobtrusive --save import SlidingMarker = require('marker-animate-unobtrusive'); Unfortunately, when I try to access th ...

Is there a way to prevent the URL of my Next.js app from constantly changing?

Our current Next.js project requires that the static URL remains constant, even when navigating between pages. This is a client requirement that we must adhere to. Can you provide suggestions on how we can achieve this? Maintaining the same URL throughout ...