0

For the past couple of weeks, I was working on creating a simple visual display of some data as bullet points. I already have a solution for the title but I wanted to post this question, to hopefully become a better engineer.

Here is a list of relevant information:

  • The frontend is React with Typescript.
  • The data required for the display has already been retrieved and stored as class fields. Something like:
public typeId: SomeEnumType;
public interestingDescription?: string;
public interestingDatapoint: number;
public importantDatapoint: string;
  • Some bullet points are conditional on (multiple?) other fields.
  • Some bullet points require a default value if they are not defined.
  • Some bullet point data needs to be transformed in some way. i.e. A value needs to be in a format.
  • Each bullet point has a specific section that it belongs to.
  • The order of the bullet points matters, but only if the bullet point must be displayed. Otherwise, the order isn't super important, although if it has a visual impact, it does.
  • The solution should be as performant as realistically possible. (Also not want to rely on 3rd party packages)
  • Changing the order or output of the bullet points shouldn't be too difficult.
  • Each bullet point has a title that has a corresponding translation key in a translation file.
  • Each bullet point has a value that may or may not require a translation.

Here are the potential solutions I've thought of:

The ideal:

Return only the fields mapped to the class that is relevant to be displayed. That way you only really need to care about whether the data is defined, mandatory, or needs a minor transformation. Unfortunately this isn't really an option for me.

Attempt 1:

Preprocess as much of the data as possible beforehand, and associate the data with whatever it needs to successfully create the bullet point. I tried to do this by doing something like this:

export const section1: SomeUnionTypeDependingOnSituation = [
   {
      titleTranslationKey: 'translation.field',
      definedObjectFieldNames: 'importantDatapoint',
      valueTransformer: functionNameThatWillSpitOutTheValueWhenPassedTheFieldName,
      isMandatory: true,
      ...
   },
   { ... }
];

The plan was to loop through this array and use the fields in each object to create a leaner object to render. My thought process was that if the processing step was only done once, and the output values are put into the lean object to render, the garbage collector could clean up the references used in the configuration object.

I gave up on this solution when I found out that I couldn't restrict the data based on the type of a dynamic field. i.e class field is of type this, skip all the other steps because you can't show it.

Attempt 2 (the current solution I am going with):

This is the solution that my coworker thought would be better, and what I am going to stick with. Essentially I have made a child class of the class containing all the references I need. In this class I have made all of the functions for the bullet points that require values based on certain conditions.

I made a child class of the class with all of the function definitions (there was 30 functions and I didn't want to bloat the class further). In the child class I defined what each section was supposed to contain:

interface RowConfig {
   titleTranslationKey: string,
   rowValue: string,
   valueRequiresTranslation?: boolean,
}

section1: RowConfig[] = [
   this.getSimpleRowConfig('importantDatapoint'),
   this.getSpecificFieldBulletPoint, // using a getter in the parent class
   this.getCommonTitleConfig('commonTitleTranslationKey', this.interestingDescription),
];

To minimize duplication I use a string input that exactly matches the name of the field in the data class and the translation key, which when called internally does something like:

getSimpleRowConfig(fieldKey: string) {
   titleTranslationKey = 'section-details.' + fieldKey;
   rowValue = this[fieldKey];
}

I wanted to know if there was a smarter way to do this, or a way that does require so many magic values. I wanted to minimize how much data I'm sending over the network so I would be hesitant to create another mapping object to keep the string keys in. If anybody has any thoughts on how they would approach the problem, I would be all ears. Thanks for reading this far!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.