Optimal strategies for handling dynamic Javascript data objects in Typescript

Currently, I am developing a Typescript tool that deals with managing state by receiving data in the form of JSON objects and updates to those objects. My goal is to merge these objects together, expecting updates to existing properties most of the time, but also allowing for additions. The challenge lies in not knowing the structure of these objects during design time.

For instance, consider starting from an initial object like:

{
    "kitchen": {
         "door": "closed",
         "cooker": "off",
         "objects": [ "saucepan", "fork", "chopping board", "fresh coriander"]
         "people": {}
    }
}

Subsequently, receiving a series of updates resembling the following:

  // update 1 
   { 
       "kitchen": { 
              "door": "open";
        }
    }

  // update 2
    {  
        "kitchen" : {
              "people": { "basil": { "wearing": ["hat", "glasses"], "carrying": [] } }
        }
    }

  // update 3
   
    {  
        "kitchen" : {
              "people": { "basil": { "carrying": [ "fork" ] } }
             "objects": [ "saucepan", "chopping board", "fresh coriander"]
        }
    }

And so forth.

The desired end result of this process is to have the object structured as follows:

{
    "kitchen": {
         "door": "open",
         "cooker": "off",
          "people": { "basil": { "wearing": ["hat", "glasses"],  "carrying": [ "fork" ] } }
         "objects": [ "saucepan", "chopping board", "fresh coriander"]
    }
}

It is important to note that the incoming and outgoing objects will be pure data represented in JSON format.

In order to achieve this, I aim to analyze the structure of the object, pinpointing changes and updates. While this task may be straightforward in Javascript, TypeScript requires a more structured approach which poses some limitations, especially since predefined interfaces won't be available within this module. The emphasis remains on ensuring new properties are added when necessary and existing ones are updated accordingly.

My inquiry is: What would be the most effective method to tackle this issue in Typescript? I seek a means to dissect the objects, treating them as nested dictionaries for comparison purposes, or recommendations on existing NPM modules that could assist in this specific scenario. It wouldn't come as a surprise if there already exists a module catered towards this purpose which has eluded my search thus far.

Answer №1

My current method involves utilizing JavaScript with typed objects, where I have created a function that looks like this:

public deepUpdate(original: any, update: any): Object {
    for (let attr in update) {
        if (original.hasOwnProperty(attr)) {
            let novel = update[attr];
            let orig = original[attr];
            if (orig instanceof Object) {
                if (Array.isArray(orig)) {
                    original[attr] = novel;
                } else {
                    original[attr] = this.deepUpdate(orig, novel);
                }
            } else {
                original[attr] = novel;
            }
        } else {
            original[attr] = update[attr];
        }
    }
    return original;
}

While my approach may not include thorough array comparisons - as there is no value-wise comparison involved - it successfully addresses the issue in a fundamental manner.

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

Angular 5 offers the capability to use mat-slide-toggle to easily display and manipulate

I am experiencing an issue with displaying data in HTML using a mat-slide-toggle. The mat-slide-toggle works correctly, but the display does not reflect whether the value is 1 (checked) or 0 (unchecked). Can anyone provide some ideas on how to resolve this ...

Inject JSON data into an HTML page as it loads continuously

Currently in the process of developing a multi-step page using ASP.NET and C#. The initial request came from an HTML page to trigger the ASP.NET page. An important aspect I am focusing on is finding a way for the ASP.NET page to send real-time status upda ...

Exploring the MapQuest API through the eyes of users

Is there a way to retrieve the list of states that a route goes through using this api? I'm looking for information on which states are crossed from the starting point to the end point. It would be ideal if the list could be generated in the order tha ...

What steps should I take to resolve the issue where ""'T' could be instantiated with a different subtype of constraint - ts(2345)""?

I've been researching various resources to find a solution for the error I'm encountering, but haven't found one that fits my specific case. My goal is to populate dummy rows in my web application so that I can use them as placeholders for ...

Can you recommend a third-party service that is compatible with both iOS4 and iOS5?

Is it possible to create a web-service based application using a third-party JSON library that can be compatible with both iOS5 and iOS4? It should be able to run on both versions as iOS5 does not support third party JSON libraries, while iOS4 does not sup ...

The data visualization tool, Highcharts, is not displaying graph components or the

Hello, I am currently setting up a basic highchart and have encountered an issue that I've been struggling to fix. I'm using AJAX to capture a JSON object and display it as a graph. However, only the title label, yAxis label, and series are appe ...

Nuxt encountered an issue with Vue hydration: "Tried to hydrate existing markup, but the container is empty. Resorting to full mount instead."

I'm facing an issue while trying to integrate SSR into my project. I keep encountering this error/warning. How can I pinpoint the problem in my code? There are numerous components in my project, so I'm unsure if I should share all of my code, b ...

The title tag is missing in the head section of a Next.js 13.4 application

I'm currently working on a project using Next.js version 13.4. I have included a title and description within the metadata, but for some reason, it is not showing up on the browser. "use client"; import Navbar from "@/components/Navbar& ...

React Hook Form - Unable to pass an array of strings as a constant to useWatch and make it work

I am eager to monitor specific fields in my component while ensuring that I pass in a constant as an array. This way, I can maintain the order of fields consistently throughout the app and easily track which fields have been updated. I attempted a simple a ...

Angular 14: Removing elements from FormArray causes the remaining elements to lose their values

My form includes custom inputs and utilizes the ControlValueAccessor. To view the implementation, visit this link. I encountered an issue where deleting an item from a FormArray would inadvertently clear the values of the other FormGroups still present in ...

What is the best way to incorporate an expression into a package.json file?

Query: Is there a way to automatically increase the version in a script message? I need my release message to always be one version higher than the previous. Aim: For example, if I have version **0.1.2**, I would like to update my commit message to 0.1.3 ...

Updating column names in Laravel web API creation process

I am facing an issue while creating a web API using Laravel. Whenever I retrieve data from a query, it returns the data with the actual table column names. For example, if I fetch data from the user table, it looks like this: { ["first_name":"John", "la ...

Changing base64 data to 9 patch format for .png images on Android devices

Currently, I'm facing an issue with sending multiple 9 patch .png image files from my PHP server to my app. To achieve this, I am base64 encoding the images on the server side like so: $img = fread(fopen($filepath, "r"), filesize($filepath)); $bin_im ...

Transforming a JSON/dictionary string into a format compatible with Python requests for improved functionality

After struggling to extract data from a poorly formatted JSON-like document, I finally had to seek assistance. My current approach involves retrieving the data and trying to convert it into a normal dict. The code snippet below demonstrates my current meth ...

"Modifying a sub-array within a JSON object using a RESTful API in the MEAN

Having trouble updating a document that is already saved in MongoDB for my MEAN stack application. I've read that using patch instead of post in my REST API paths is the way to go, but it's still a bit unclear to me. Specifically, I need to add a ...

unable to retrieve getters within the store module

This is the explanation of my store module. // rest defined earlier const _GETTERS = { getName: state => { return state.current.name; }, getLastName: state => { return state.current.lastName; }, getFullName: (state, getters) => ...

Transform C# datetime into JSON serialized date string

Can someone offer me some assistance here? I am facing an issue while trying to make an API call by sending a JSON object to it. I am having difficulty converting C# datetime to the correct JSON format. Below is a snippet of my code. HttpWebRequest htt ...

Bringing in the RangeValue type from Ant Design package

Currently working on updating the DatePicker component in Ant Design to use date-fns instead of Moment.js based on the provided documentation, which appears to be functioning correctly. The suggested steps include: import dateFnsGenerateConfig from ' ...

An error occurred while attempting to parse a JSON string using the Jackson library

Below is the JSON data I am attempting to parse utilizing the Jackson Java library. It represents a Vector of BackgroundShapes, where BackgroundShape subclasses include: BGRectangle BGCircle Within this JSON snippet, there are 2 BGRectangles, but it ma ...

The constructor for Observable, as well as static methods such as `of` and `from`, are currently

I encountered a challenge in my angular application while trying to create an observable array using rxjs. Here is the code snippet: import { Injectable } from "@angular/core"; import { Observable } from "rxjs/Rx"; import { User } from "../model/user"; ...