Ensuring data integrity by validating incoming data with TypeScript and Angular 2

What is the best approach to validate data received from the server using AJAX or in a child component using the @input decorator in Angular2+ applications? In my current project, I utilize interfaces for this purpose, however they do not entirely validate incoming data. For instance, no runtime errors are issued if some property is missing or has an invalid type:

// types.ts
export interface IAuthItem {
name: string;
type: number;
description: string;
rule_name: string | any;
data?: any;
created_at: number;
updated_at: number;
selected?: boolean;
}

export interface IAuthItemFormModel {
AuthItem: IAuthItem;
oldAuthItem: IAuthItem;
permissions: IAuthItem[];
assignments: IAuthItem[];
}

// component.ts

//other imports
import { IAuthItemFormModel,  IAuthItem  } from './types.ts';

....

@Input() model: IAuthItemFormModel;

  ngOnInit() {
  this.getData();
}

getData() {
  this.http.post('/api/admin/auth-item/form-data', 
    this.model).subscribe((data: IAuthItemFormModel) => {
  this.model = Object.assign(this.model, data);
  console.log(this.model);
  });
}

Answer №1

DISCLAIMER: The following example demonstrates a potential approach, and it may not necessarily be valid or required. This approach has been personally used recently for its flexibility and adaptability.

Let's get straight to the point.

Since interfaces do not exist in runtime, if you intend to parse data effectively and apply any kind of "test" to obtain the desired information and manipulate the acquired data, utilizing classes is recommended.

Here is an illustration simulating a sample response:

const json_response = {
    status: "done",
    refere: {
        "id": 13,
        "name": "John"
    }
};

In this scenario, I will implement a Response Handler that manages the entire response and a Referee class responsible for handling the referee reference as well.

Let's start with the Referee class:

interface IReferee {
    id: number,
    name:   string
}

class Referee implements IReferee {
    public id: number;
    public name: string;

    private rawData: any;

    constructor(data?: any) {
        if (data !== null) {
            // Perform necessary checks to ensure data coherence.
            this.id = +data.id;
            this.name = data.name;
        }
    }

    get ID(): number {
        return this.id;
    }

    get LowerCaseName(): string {
        return this.name.toLowerCase();
    }

    get Name(): string {
        return this.name;
    }

    get UpperCaseName(): string {
        return this.name.toUpperCase();
    }
}

The interface is optional but useful for ensuring correct implementation in the class. It also allows customization of methods as shown above.

Next, the response handler:

interface IMyJsonResponseHandler {
    status: string,
    refere: Referee 
}

class MyJsonResponseHandler implements IMyJsonResponseHandler {
    private rawData: any;

    public status: string;
    public refere: Referee;

    constructor(data?: any) {
        if (data !== null) {
            this.status = data.status;
            this.refere = new Referee(data.refere);
        }
    }

    get Refere(): Referee {
        return this.refere;
    }
}

Similarly, thorough processing is done in the constructor based on the JSON response provided. Strict checks can be added here along with error handling. Using classes and interfaces provides easy access and understanding of properties within the JSON response.

Example usage:

const json_response = {
    status: "done",
    refere: {
        "id": 13,
        "name": "John"
    }
};
let res = new MyJsonResponseHandler(json_response);

console.log(res.Refere.LowerCaseName);

You can experience intellisense benefits through the utilization of interfaces and classes together.

If your data processing requirements are complex or involve instantiating inner properties as class instances, implementing classes is preferable over just using interfaces.

Additional resources worth exploring:

How to parse JSON string in Typescript

How do I cast a JSON object to a typescript class

Answer №2

In JavaScript, interfaces do not exist, but TypeScript is considered a superset of JS and can be transpiled into JS for browser compatibility.

Interfaces in TypeScript are primarily used to provide Intellisense suggestions and catch compile-time errors during development.

If you need to validate an object in JS, one way is to examine the parameters using methods like getOwnPropertyNames.

https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/getOwnPropertyNames

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

Troubleshooting issue with image dimensions in Angular within CKEditor content

One issue I am facing is with CKEditor, where images inserted into Rich Text Fields have their height and width attributes set in a CSS style tag. For example: <img alt="" src="https://something.cloudfront.net/something.jpg" style="height:402px; ...

Calculating the product of numbers within an HTML table based on designated column headers using IONIC instructions

Issue: In my HTML table, there are three columns labeled as Price, Quantity, and Total. Numbers are entered under each column. Objective: My goal is to automatically calculate the value in the Total column by multiplying the values in the Price and Quanti ...

Is there a way to retrieve a compilation of custom directives that have been implemented on the Vue 3 component?

Is there a way to retrieve the list of custom directives applied to a component? When using the getCurrentInstance method, the directives property is null for the current component. I was expecting to see 'highlight' listed. How can I access the ...

Optimize your Kendo components in Angular with this top-notch customization strategy

How can kendo components like grids and charts be styled in the best possible way while following recommended practices? My current methods of styling them are: 1 : Utilizing ng deep, host, however these approaches have been deprecated and are not consi ...

Uh oh! An issue occurred: StaticInjectorError(AppModule)[UserformService -> HttpClient] - There seems

After attempting to incorporate a PrimeNG table into my project, I encountered issues with my build. You can view the broken state of my code at https://github.com/BillyCharter87/Tech-O-Dex-UI/tree/BrokeIt I believe the problem arose when I updated my pac ...

Tips for securely passing props based on conditions to a functional component in React

I came across this situation: const enum Tag { Friday: 'Friday', Planning: 'Planning' } type Props = { tag: Tag, // tour: (location: string) => void, // time: (date: Date) => void, } const Child: React.FC<Props> = ...

Potential Null Object in Typescript Mongoose: A Concern

Encountering an issue while attempting to locate my user model: Object is possibly 'null'. I would like to find a solution that does not involve suppressing TypeScript's strict rule. const { email, password } = req.body; const user = awai ...

Turning HTML into PDF using Angular 10

I am having success generating a PDF from my HTML page when the data is bound to td directly from ts. However, I face issues when trying to bind the value to an input. You can see a working example on Stackblitz. Generating a PDF for my ...

The response of the Typescript Subscription function

I'm struggling with retrieving the subscribe array in NG2. Being new to typescript, I find it difficult to understand how to pass variables between functions and constructors. This is what my code currently looks like: export class RosterPage exten ...

Cannon-js: Experience dynamic body bouncing on the y axis as it reacts to force applied on the x and z axes

Currently, I am working on an FPS game where the player controller applies force based on keyboard inputs to a dynamic cannon body. The angular dampening is set to 1 on the player body. The PlayerController class takes both the player class (which extends ...

Combining multiple 'Eithers' and 'Promises' in fp-ts: A guide to piping and chaining operations

Recently, I began working with fp-ts and wanted to create a method with functional-like behavior that would: Parse a bearer token Verify the validity of the user using the parsed token import { Request } from 'express'; import { either } from & ...

The functionality of changing the source to the "docs" folder is not supported

I'm currently working through a tutorial on deploying to GitHub Pages. You can find the tutorial here. Based on my understanding of the following command: ng build --prod --output-path docs --base-href /<project_name>/ I am using the Angular ...

Monitor constantly to determine if an element is within the visible portion of the screen

For a thorough understanding of my query, I feel the need to delve deeper. While I am well-versed in solving this issue with vanilla Javascript that is compatible with typescript, my struggle lies in figuring out how to invoke this function throughout th ...

Encountering TypeScript error TS2339 while mocking a React component with Jest

When attempting to mock a React component using Jest, I encountered an issue where TypeScript was not recognizing the mocked methods and showing a TS2339 error. Below is the test code snippet causing the problem: jest.mock('./features/News/News' ...

Numerous unspecified generic arguments

Imagine a collection of functions, each capable of taking an argument and returning a value (the specifics don't matter): function convertToNumber(input: string): number { return parseInt(input) } function convertToBoolean(input: number): boolean { ...

Encountered an issue in Angular 6: Unable to access property '0' of undefined

There's an error popping up in the console saying, Cannot read property '0' of undefined, but surprisingly I'm still getting the expected result. Below is my HTML code snippet: <div class="col-md-3"> <div class="slider-prod ...

Testing the GET method in an Angular service: A guide

I'm currently facing an issue with my service method and unit test setup. Despite writing a unit test for the getter method, the coverage report indicates that this method is not covered. I would appreciate any advice on what might be going wrong in m ...

Guide to implementing a specified directive value across various tags in Angular Material

As I delve into learning Angular and Material, I have come across a challenge in my project. I noticed that I need to create forms with a consistent appearance. Take for example the registration form's template snippet below: <mat-card> <h2 ...

Obtain the content of a clicked item on the following page using NextJs

I am currently working on a nextjs app that displays a list of 10 movies on the homepage, each with a Button / Link that leads to a specific page for that movie where all its content is shown. Initially, I tried adding the movie id to the Link like this: ...

Error in Deno pooling map server due to unhandled AggregateError

I am trying to run this TypeScript code snippet import { serve } from "https://deno.land/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eb989f8d9cdbc5dbd9dac5db">[email protected]</a>/http/server.ts" imp ...