Guide for triggering an exception when the format of one object does not match another object

When reading user input objects, it is important that they are well-formed.

This means that the input objects may not have any key or sub-structure that is not defined in the interface.

What is the best way to handle an exception if a user provides an invalid object?

Interface Definition

  export interface InputStructureInterface {
      "tableName": string,
      "viewType": string,
      "structureName": string,
      "sections": Array<Section>,
  }

  interface Section{
      "name": string,
      "fields": Array<Field>
  }

  interface Field{
      "fieldName": string,
      "relationType": string,
      "relationName": null,
      "fieldUi": FieldUi
  }

  interface FieldUi {
      "fieldType": string,
      "label": strin
  }

Valid Input Structure

This structure falls within the defined InputStructureInterface

  {
    "tableName": "User",
    "viewType": "List View",
    "structureName": "personal_data_settings_list_view",
    "sections": [
      {
        "name": null,
        "fields": [
          {
            "fieldName": "Name",
            "relationType": null,
            "relationName": null,
            "fieldUi": {
              "fieldType": "string",
              "label": "Name"
            },
          }
        ]
      }
    ]
  }

Invalid Input Structure

The presence of viewTypeTHIS_IS_A_TYPO and nameTHIS_IS_A_TYPO indicate invalid input as these keys are not part of the interface definition.

{
  "tableName": "User",
  "viewTypeTHIS_IS_A_TYPO": "List View",
  "structureName": "personal_data_settings_list_view",
  "sections": [
    {
      "nameTHIS_IS_A_TYPO": null,
      "fields": [
        {
          "fieldNameTHIS_IS_A_TYPO": "Name"
        }
      ]
    }
  ]
}

Answer №1

The TypeScript language is mainly used for enforcing types during compile time. If you need to perform validations like the one shown in the code snippet below, you would typically utilize a json-schema validation library. One example of such a library is available at this link: https://github.com/epoberezkin/ajv

UPDATE

For instance, with the help of a library such as the one mentioned above (https://github.com/epoberezkin/ajv), you can implement something similar to the following:

import * as Ajv from 'ajv';
const ajv = new Ajv();

const schema = {
    "type": "object",
    "properties": {
        "tableName": { "type": "string" },
        "viewType": { "type": "string" },
        "structureName": { "type": "string" },
        "sections": {
            "type": "array",
            "items": [
                {
                    "type": "object",
                    "properties": {
                        "name": { "type": ["string", "null"] },
                        "fields": {
                            "type": "array",
                            "items": [
                                {
                                    "type": "object",
                                    "properties": {
                                        "fieldName":	{ "type": "string" },
                                        "relationType": { "type": ["string", "null"] },
                                        "relationName": { "type": ["string", "null"] },
                                        "fieldUi": {
                                            "fieldType": { "type": "string" },
                                            "label": { "type": "string" }
                                        }
                                    },
                                    "required": ["fieldName", "relationType", "relationName"],
                                    "additionalProperties": false
                                }
                            ]
                        }
                    },
                    "required": ["name", "fields"],
                    "additionalProperties": false
                }
            ]
        }
    },
    "required": ["tableName", "viewType", "structureName"],
    "additionalProperties": false
};

const validate = ajv.compile(schema);
let valid = validate(data); // <-- pass your json object here

if (!valid) {
    console.log(validate.errors);
}

To add the library to your project, use the command: npm install ajv

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

Utilizing Angular 2's pipe functionality with dynamic parameters

Currently I am diving into Angular2/Ionic2 and trying to grasp the concept of Pipes. Everything was going smoothly until I faced a roadblock in the form of a specific problem related to temperatures. Let me illustrate my issue with an example involving te ...

React TypeScript throws an error when a Socket.IO object is passed to a child component and appears as undefined

Currently, I'm developing a simple chat application as part of my university course. The code below represents a work-in-progress page for this project. While I am able to get the socket from the server and use it in the main component without any is ...

Having trouble making the child process die in NodeJS fork

I'm facing a roadblock here, perhaps it's just a minor issue that I can't seem to solve because of my lack of experience with NodeJS. Currently, I am developing a Bluetooth device that will be controlled by a master application. For prototy ...

``The presence of symlink leading to the existence of two different versions of React

Currently, I am working on a project that involves various sub custom npm modules loaded in. We usually work within these submodules, then publish them to a private npm repository and finally pull them into the main platform of the project for use. In orde ...

Looping through an array of objects with Angular 4's ngFor directive to dynamically display content

I am working with Angular 4 and I am attempting to iterate through an array of objects to present the data in Angular Material grid tiles. The code snippet from my HTML file (app.component.html) is as follows: <div class="list" *ngIf="listContacts == t ...

Is there a method to make .load work on Chrome?

Currently, I have a straightforward function that retrieves image data and then displays it. Following this, the script executes the sizeImages() function to resize the image in proportion to the browser size. The issue at hand is that this functionality ...

Slide up a row in the table using jQuery

Currently, I am in the process of creating a unique jQuery plugin that enables users to instantly delete records within a table. One key feature I would like to implement is changing the background-color of the deleted row to red and then smoothly sliding ...

The type 'Event' argument cannot be assigned to the 'InfiniteScrollCustomEvent' parameter

I'm facing an issue with Ionic Angular. Here is my movies.page.html: <ion-header> <ion-toolbar color="primary"> <ion-title>Trending Movies</ion-title> </ion-toolbar> </ion-header> <ion-content ...

Discrepancy in post results

I am currently working on integrating two scripts - a Prestashop DHL label creator and our company's internal sales application. The goal is to streamline the process of generating DHL labels directly from our sales application without the need to acc ...

Is there a way to automatically hide a div based on a checkbox value when the page loads?

How can I hide a div in my view when a checkbox is not checked upon page load? <input type="checkbox" class="k-checkbox" id="chkInvoiceStatusActive" asp-for="InvoiceStatus" value="true" /> <input t ...

Pressing the button will add text into the input field

Below is a jsfiddle link showcasing the current issue I am trying to address: http://jsfiddle.net/YD6PL/61/ Here is the HTML code snippet: <input type="text> <input type="text> <input type="text> <div> <button class="buttons"& ...

The table from datatables.net is failing to load with Ajax requests

Having trouble with v1.10 Datatables.net table not loading via ajax? The examples and documentation at datatables.net didn't provide a solution. Despite the table displaying, it shows "No data available in table". This issue is occurring in an older M ...

The logic is not quite coming together in these arguments

//Resolved In my attempt to add the parameters together and then divide by 2 to pass the result into the sqrt method, I encountered an issue where only the last parameter of the function was being returned. When using typeof, it indicated that the argume ...

Troubleshooting color inconsistency in ApexCharts tooltips using JavaScript

My attempt to change the tooltip color to black seems futile as it continues to display in white. Consequently, when a user hovers over the graph, it remains in its unaltered state with poor user design. To gain better insight, refer to the image below: h ...

Prefix not being recognized by bot

After experiencing multiple bugs with my previous bot, I've decided to start fresh and create a new one. However, despite my efforts to write the code smarter this time, I have encountered some difficulties. Unfortunately, I couldn't even get pas ...

Typescript code pointing to a specific file location

MainDirectory |_bin |_config |_source > myfile.ts I am currently learning about typescript and I am trying to reference a file located in a different folder. Specifically, I have created a new folder called Folder1 within the config directory, which co ...

Kids in the realm of useCallback are stuck in dependency pur

My understanding of useCallback was to prevent rerendering, so I've implemented it in all my functions. However, I have a feeling that this might not be the best approach. What's even worse is that by using it everywhere, I am passing dependenci ...

Best method for combining objects in a tidy manner

I have multiple objects with similar structures, where some have null values for certain fields and one object (obj2) has values for those fields that are null in the others. I want to merge them and consider the values from obj2: var obj2 = { options ...

What purpose does the by.js locator serve in Protractor/WebDriverJS?

Recently, I've come across a new feature in the Protractor documentation - the by.js(): This feature allows you to locate elements by evaluating a JavaScript expression, which can be either a function or a string. While I understand how this locat ...

Is it true that Javascript's onclick global event handlers fire prior to the page being fully loaded

I'm trying to set a global event handler for an image, but running into issues. When I use the code document.getElementById("post_image").onclick = photoEnlarge;, it returns an error saying Uncaught TypeError: Cannot set property 'onclick' ...