How can we reduce the size of a JSON object in Typescript before sending it to the client?

Currently, I am faced with a common challenge. I have a database object that is a standard JS object originating from a document database, and my goal is to transmit this object to the client. However, certain fields contain sensitive information that should not be exposed to the client.

In the realm of C#, I would typically utilize Declarative Reflective programming by attaching attributes to my C# object, specifying which fields are safe for client use as demonstrated below:

[SafeForClient]
string MyProperty { get; set; }  // send to client. 

string SecretData { get; set; }  // Do NOT send to client. 

I would then employ reflection to collect all properties marked with [SafeForClient], compile my JSON, and transfer it over to the client. Unfortunately, JavaScript lacks such declarative metaprogramming capabilities at this level.

In TypeScript, I define my types as follows:

export type RoomForClient = {
    id: number;
    name: string;
    description: string;
    exits: {[index in Direction]?: Exit }
}

export type Room = RoomForClient & {
    hiddenFlags: ScriptData;
}

The room data sent to the client represents only a subset of the complete room data. Currently, if there is one property that should not be included, I can simply remove that attribute from the object. However, as more properties are introduced in the future, I will need to specify those property names in two locations - once in the Room definition and again in the method responsible for trimming down the object.

How can I generate a "RoomForClient" object from a "Room" object without manually listing all the fields that should or shouldn't be copied? Since all type information is removed at runtime, I am struggling to devise a solution that doesn't violate the DRY principle, which I consider a code smell.

Any suggestions?

Answer №1

If you're looking for a way to annotate your properties in TypeScript, you may want to explore the use of Property or Accessor Decorators.

One approach is to define your properties using decorators like this:

export type RoomForClient = {
    @SafeForClient
    id: number;
    ...
}

Please keep in mind that incorporating decorators like this will necessitate including the reflect-metadata library.

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

Is there a way to display an image in a React Native app using data from a JSON file?

I am currently working with JSON content that includes the path of an image. I need to display this image in my React Native application. What is the best way to render this image? {"aImages":[{"obra_path":"http:\/\/uploa ...

Locating the source of the function call within a file in Node.js

Is it possible to determine the location of a file if a method from a module is called within that file? For example: // my-module.js module.exports = { method: function () { // I would like to know the path to my-app.js here } } // my-other-mod ...

implementing toggle functionality for an array of items in ReactJS

I have an array and I am trying to create a show/hide feature for each item based on toggling. When I click on one item, it should expand while simultaneously hiding the previously expanded item. Here is the code snippet I have been working on: class App e ...

Retrieving JSON information from a URI in PHP without relying on cURL

Recently, I encountered a scenario where I needed to retrieve data from a URI returned in JSON format on my IIS machine with PHP. The specific URL was: The challenge was that I couldn't utilize cURL for this task. Is there an alternate method to acco ...

The type 'undefined' cannot be assigned to a different type within the map() function, resulting in a loss of type information

I am facing an issue in my redux toolkit where an action is trying to set some state. Below is the relevant code snippet: interfaces export interface ProposalTag { id: number; name: string; hex: string; color: string; } export interface ProposalS ...

Disabling form submission when pressing the enter key

Is there a way to prevent a submit action from occurring when the enter key is pressed within an ASP:TextBox element that triggers an asyncpostback upon text change? Instead, I would like it to click on another button. The Javascript function I am using wo ...

Tips for avoiding the transmission of className and style attributes to React components

Hey there! I'm working on a custom button component that needs to accept all ButtonHTMLAttributes except for className and style to avoid any conflicts with styling. I'm using TypeScript with React, but I've run into some issues trying to ac ...

Improved methods for extracting nested JSON data from a Spark table

As a newcomer to Spark and Scala, I am facing the challenge of parsing a Nested JSON format column from a Spark Table. Let me show you an example row from the table: doc.show(1) doc_content object_id object_version {&quo ...

Issues arise when using Jquery events in conjunction with AngularJS causing them to function

I have encountered an issue with my AngularJS menu code. I am sending an array to prepare the menu when the document loads. In this sequence, I have also added a click event to the generated menu. However, the click event does not fire if it is placed befo ...

Implementing an interactive tab feature using jQuery UI

Recently, I was working on a project involving HTML and jQuery. Now, my goal is to create a dynamic tab with specific data when a button is clicked. This is my code for the JQuery-UI tab: $(document).ready(function() { var $tabs = $("#container-1 ...

How can I transfer a PHP variable into a JavaScript variable nested within another PHP variable

After my php/html script generates the image, I am looking to display it without needing to reload the page. I currently call a javascript function within the PHP code to change the image. However, I am unsure how to pass the new image name to this javasc ...

Connect button with entry field

I want to create a connection between an input element and a button, where the button triggers the input and the input remains hidden. Here is a solution that I came across: <a href="javascript:void(0)" id="files" href=""> <button id="uploadDe ...

What sets JSON arrays apart from JSON objects?

What distinguishes the use of JSON arrays from JSON objects and what are their respective advantages? { arrayExample:[ { /* items */ }, { /* items */ } ] } Vs. { objectExample:{ { /* properties */ }, { /* properties */ } ...

Keep an ear out for socket.io within an Angular application

I am trying to connect socket.io with my angular application. I have come across some examples of creating a service that can be accessed by the controller, and I understand that part. However, I am looking for a solution where all controllers can respond ...

Access the properties of a JSON object without specifying a key

I am dealing with a collection of JSON arrays structured like this: [ { team: 111, enemyId: 123123, enemyTeam: '', winnerId: 7969, won: 1, result: '', dat ...

What are the steps to resolving an Unhandled promise rejection error in a Node.js application?

I encountered an error message that I need help resolving: I am faced with an unhandled promise rejection. This issue likely occurred due to throwing inside an async function without a catch block, or rejecting a promise without handling it using .catch( ...

The polygon array feature is not functioning as expected in the Google Maps API

I'm currently facing an issue with a code that is supposed to draw polygons from an array in the Google Maps API, but unfortunately, it doesn't seem to be working as expected. <!DOCTYPE html> <html> <head> <script src ...

Tips for including a currency symbol before an input field using Material UI

Trying to add a dollar sign to the left of an input field using InputAdornment but it's not displaying correctly. Check out my code here: https://codesandbox.io/s/material-demo-wnei9?file=/demo.js ...

Timer Does Not Appear to be Counting Down

I recently added a countdown clock to my website, but I'm having an issue with it not updating in real-time unless the page is refreshed. I'm not very familiar with javascript, so I found some code online and made some modifications myself to sui ...

Instructions for overlaying a text onto the select input field in DataTables

I am currently utilizing the DataTables select input feature to capture only the first three columns of data. However, I would like to enhance this by adding a text element above the select inputs within the DataTables interface. Is there a way to achieve ...