Connecting Angular Objects Together

Although I'm not very experienced with Angular, there's a task at my job that requires me to handle it. The task involves a form where users input values and these values are sent directly to the backend for processing. The form is used to submit a PolicyDocument which consists of the following parameters:

import {ContactFrequency} from './ContactFrequency';

export class PolicyDocument {
    id: number;
    name: string;
    description: string;
    file: string;
    validFrom: string;
    country: string;
    majorVersion: number;
    minorVersion: number;
    status: string; // TODO dmann make enum or string set
    primaryText: string;
    secondaryText: string;
    textBlocks: TextBlock[];
    contactFrequency?: ContactFrequency;

    constructor() {
    }
}

The ContactFrequency class looks like this:

export class ContactFrequency{
    id:number;
    contactFrequency: number;

    constructor() {
    }
}

And here's how the form collects values:

<label for="inputContactFrequency" class="col-1 col-form-label">Contact Frequency (Days)</label>
<div class="col-2 pr-0">
    <input type="number" class="form-control" id="inputContactFrequency" placeholder="(Optional)"
           [ngModel]="detail?.contactFrequency?.contactFrequency"
           name="contactFrequency.contactFrequency" [disabled]="fieldsDisabled()" min="0"/>
</div>

Apologies for the inconsistent naming convention. My issue is when I input a value, the payload sent to the backend looks like this:

contactFrequency: 180

If no value is inserted, it appears as:

contactFrequency:{
   contactFrequency: null
}

It works fine when no value is inserted, but when a value is entered, it does not get passed as an object. Is there a simple way to modify it so that it passes an object to the backend instead?

After filling out and submitting the form, the handleCreate method is triggered:

handleCreate(policyDocument: PolicyDocument) {
    this.userFeedbackService.clearAllUserFeedback();
    if (this.validatePolicyDocumentDate(policyDocument)) {
        this.policyDocumentService.create(policyDocument).subscribe(
            (response) => {
                console.log('handleCreate returned ', response);
                this.router.navigate(['/policies'])
                    .then(() => this.userFeedbackService.clearAndAddSuccess('Policy created successfully'));
            },
            () => {
                this.removeDefaultValidityInDays();
                window.scrollTo({top: 0, behavior: 'smooth'});
            });
    } else {
        window.scrollTo({top: 0, behavior: 'smooth'});
    }
}

Subsequently, the process moves on to the service function:

create(policyDocument: PolicyDocument): Observable<PolicyDocument> {
    console.log("Policy Document for frequency rule: " + policyDocument);
    console.log("Contact Frequency for frequency rule: " + policyDocument.contactFrequency?.contactFrequency);
    return this.http
        .put(POLICY_DOCUMENTS_API, policyDocument)
        .map(data => {
            this.userFeedbackService.clearAndAddSuccess('Policy document has been created successfully');
            return <PolicyDocument>data;
        })
        .catch((err) => {
            this.userFeedbackService.addError('Failed creating policyDocument');
            throw new Error(err.toString());
        });
}

Answer №1

Upon my observation, the following request returns a null value which is acceptable because this property is defined by the ContactFrequency model:

contactFrequency:{
   contactFrequency: null
}

... Therefore, when entering text, the input functions as a numerical attribute. This is good! The issue arises when you need to intercept the request before the actual HTTP request is made; at that point, you must create the object as contactFrequency:

You may have a service function similar to this:

save(data: YourModel): Observable<YourModel> {

    return this.http.post(url, data).pipe(
      catchError((err) => {
        ... code
      })
    );
  }

In your controller, you need to call serivce.save(data), and construct the object like so:

const obj: PolicyDocument = {
    bla: 'bla',
    ble: 'ble',
    contactFrequency: {
        id: 'xyz',
        contactFrequency: 180
    }
    
}

Once you have the value 180, build the object, then call service.save(data)

I recommend utilizing reactive forms as you can easily subscribe to the input and construct the value of the contactFrequency model

In my perspective, template forms should be phased out.

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

Transforming a function into an array in TypeScript

I attempted to use the map() function on a dataURL array obtained from the usePersonList() hook, but I am struggling to convert my function to an array in order to avoid errors when clicking a button. import Axios from "axios"; import React, { us ...

What is the best way to extract information from a JSON file?

Hello all, I'm facing an issue while trying to parse a JSON object in Angular. I've created a JSON object with all the necessary data in my service. In the component, I am attempting to parse this JSON and display all messages in youSend.mess ...

Struggling to successfully map angular model data to a Spring POJO class

I am currently having issues mapping an Angular model class to my Spring model class. When I try to do so, all the entities in the Spring model class show up as null. I have included the code snippets below that I used for mapping, but unfortunately, it fa ...

What causes the child component to be rendered four times when the parent component is first loaded?

I have been facing an interesting scenario with my parent and child components. Typically, change detection is triggered by events like HTTP requests or timers such as setInterval and setTimeout. However, in this particular case, I am not utilizing any of ...

Angular 10 Reactive Form - Controlling character limit in user input field

I'm currently developing an Angular 10 reactive form and I am looking for a way to restrict the maximum number of characters that a user can input into a specific field. Using the maxLength Validator doesn't prevent users from entering more chara ...

Steps to insert a personalized attribute into a TypeScript interface

UPDATED EXPLANATION: I'm fairly new to TypeScript, so please bear with me if this question seems basic. I'm working with an existing library (ngx-logger) that I don't want to or can't modify. My goal is to create a service that generat ...

Automate the compilation of Typescript project references by creating a solution that allows for passing unique options to each

When compiling or building a project with references programmatically, I make use of the ts.createSolutionBuilder API. The challenge I face is that in my specific scenario, I do not have individual tsconfig.json files stored on the filesystem for each pac ...

Xtermjs does not support copying and pasting functionalities

I'm struggling to enable the copy & paste feature in my terminal using xterm.js APIs. My goal is to allow users to copy strings from the clipboard. Currently, I have implemented the following code: this.term.onKey((key) => { if (key.domEven ...

Ways to utilize a field from an interface as a type of index

interface Mapping { "alpha": (a: string) => void "beta": (b: number) => void } interface In<T extends keyof Mapping> { readonly type: T, method: Mapping[T] } const inHandlers: In<"alpha"> = { type ...

Proper positioning of try/catch block in scenarios involving delayed async/await operations

For the past six months, I have been utilizing async/await and have truly enjoyed the convenience it provides. Typically, I adhere to the traditional usage like so: try { await doSomethingAsync() } catch (e) {} Lately, I've delved into experimenti ...

Using refresh tokens in Angular 4 to manage authentication across multiple API requests

I am currently working on incorporating the refresh token concept into my web application. When the page is refreshed, I need to make calls to 4 different APIs. If the access token expires, I have a backend process in place to retrieve a new access token ...

Issue encountered in app.module.ts while attempting to incorporate AngularMultiSelectModule

Currently, I am utilizing angular version 6 and attempting to incorporate the angular2-multiselect-dropdown in my application. Upon launching the app and following the steps outlined in this guide: and also here: https://www.npmjs.com/package/angular2-mul ...

Ways to achieve a unique design for the AppComponent component level?

I have developed an application with a menu located in the AppComponent, causing all child pages/components to inherit it as shown in the following pseudo code: <menu></menu> <--I am looking to remove this from the new page--> <router- ...

What is the method for replacing a type with a child type in a function declaration within TypeScript?

interface Parent { name: string; } interface Child extends Parent { name: string; text: string; } function myFunction(text: string, target: Child): Child { target.text = text; console.log(target); return target; } const testChild ...

Customizing variables in React based on the environment

I am working on a React app that includes a chart component which calls an external API. When the app is running locally, the API URL is set to localhost:8080. However, when the app is deployed, the API URL needs to be changed to prod:8080. I have tried ...

Exploring the DOM in JavaScript: Searching for the final ancestor containing a specific attribute

Check out this example of HTML code: <div id="main1" data-attribute="main"> <div id="section2" data-attribute="subsection"> <div id="nested3" data-attribute="sub-subsection"> </div> </div> </div> <div id= ...

In TypeScript, what is the format in which the final type result of a generic utility type is shown?

After utilizing the provided code, I have encountered an issue with retrieving the ultimate type of type A in the editor. Despite my efforts, the editor persistently showcases the composite form of the generic utility, complicating the process of verifyi ...

The parameter type 'void' cannot be assigned to the parameter type 'SetStateAction<{}>'

Currently, I am in the process of developing an application utilizing TMDB with NextJS and Typescript. Within my movies.ts file, I have implemented the following code: export async function getTrendMovies() { const url = 'https://api.themoviedb.o ...

The Angular HTTP GET request is failing to function properly as expected

I am currently working on developing the front end for an API request. The structure of the response model is as follows: export class User { ID: number; first_name: string; last_name: string; isAdmin: boolean; } Within the user.component ...

The input values passed to "onChange" are not compatible with "NativeSyntheticEvent<TextInputChangeEventData>"

I'm fairly new to React Native and encountered an issue while trying to implement the following code snippet: <TextInput style={styles.input} onChange={(text) => setPontoValue(text)} /> This error message ...