Submit user-specific form data in Angular 5 based on user selection

Utilizing a common reactive form to handle various types of user data, such as teachers, students, guards, etc. The form is selected from a dropdown list.

The goal is to send specific data objects based on the selected user type. A model named "User" has been created with both common and different fields. The data should be sent as follows:


selectedUser: string; //form selection like teacher
submit(data) {
  if(selectedUser === 'Teacher') {
    let teachObj = new User(data.name, data.address, data.degree);
    this.userService.post(url, teachObj);
  }
  if(selectedUser === 'Student') {
    let stuObj = new User(data.name, data.address, data.semester);
    this.userService.post(url, stuObj);  
  }
  ...and so on
}

Model class

export class User{
    //all fields here

     constructor(name: string, address: string, semester?: string, degree?: string)
}

Issue: Unable to overload constructor or create object with different parameters like in Java or C#

Answer №1

Create an interface that consists of both mandatory and optional properties, where some properties are required in specific scenarios as shown below

export interface IUser{
  name: string;
  address: string;
  semester?: string,
  degree?: string
}

In this interface, 'name' and 'address' are compulsory for all cases, while 'semester' and 'degree' can be provided based on certain conditions.

You can utilize this interface within the constructor of your User class to assign values to the properties like so:

export class User{
    //define all fields here
  public name: string;
  public address: string;
  public semester?: string;
  public degree?: string;

  constructor(user:IUser) {
    this.name = user.name;
    this.address = user.address;
    this.semester = user.semester;
    this.degree = user.degree;
  }

}

To instantiate the class, you can follow the approach below -

let data2:IUser = { name: data.name, address: data.address, degree: data.degree};
let techobj = new User(data2);

Alternatively, you can simplify it like this:

let techobj2 = new User({ name: data.name, address: data.address, degree: data.degree});

For creating an instance of Student, you can do it in the following manner -

let techobj3 = new User({ name: data.name, address: data.address, semester:data.semester });

The complete code snippet is presented below -

export interface IUser{
  name: string;
  address: string;
  semester?: string,
  degree?: string
}

 export class User{
    //define all fields here
  public name: string;
  public address: string;
  public semester?: string;
  public degree?: string;

  constructor(user:IUser) {
    this.name = user.name;
    this.address = user.address;
    this.semester = user.semester;
    this.degree = user.degree;
  }
}

let data:IUser = { name: "Niladri", address: "123", degree: "GRAD" };
let techobj = new User(data);

///OR 
let techobj2 = new User({ name: "Niladri", address: "123", degree: "GRAD" });

//Similarly 

let techobj3 = new User({ name: "Niladri", address: "123", semester:"6th" });

console.log(techobj2.degree); //GRAD
console.log(techobj3.semester); //6th

For service calls, structure them as demonstrated below -

selectedUser:string; //determine selected option such as teacher etc   
 submit(data){
   if(selectedUser === 'Teacher'){
     let teachobj = new User({ name: data.name, address: data.address, degree: data.degree});
        this.userservice.post(url,teachobj);
        }
   if(selectedUser === 'Student'){
     let stuobj = new User({ name: data.name, address: data.address, semester:data.semester });
       this.userservice.post(url,stuobj);  
      }
    ..... continue with other conditions
}

Note: Passing null for undesired parameters in the current constructor will also function correctly.

Edit 2: Another method involves creating a base class User and deriving sub-classes like Student and Teacher, then invoking super() in the child classes' constructors to transmit the name and address property values to the parent User class. However, this may result in numerous child classes depending on the number of conditionals present.

View the working demo at this link

Answer №2

To streamline your code, you could consider creating a base class called User that includes all the shared fields for both Teachers and Students. From there, you can create separate classes for Teacher and Student that extend the User class, adding their unique fields such as degree for teachers and semester for students. For more information on extending classes in Typescript, check out this resource: Extending Classes in Typescript.

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

Strange activities observed during the management of state in react hooks, where the splice() function ends up eliminating the

My current setup involves maintaining a state to handle the addition of new JSX elements: const [display, setDisplay] = useState<IDisplay>({ BookingFormDropDown: [], } ); I have a function in onClick() which adds an elem ...

After compilation, what happens to the AngularJS typescript files?

After utilizing AngularJS and TypeScript in Visual Studio 2015, I successfully developed a web application. Is there a way to include the .js files generated during compilation automatically into the project? Will I need to remove the .ts files bef ...

Concealed URL - Navigation with Angular 2 Routing

Is it possible to conceal the URL when using window.open()? Alternatively, can the Angular2 router be utilized to open the URL in a fresh tab? I am familiar with the method of concealing the URL during routing by using this.router.navigate(["/Pages"], { s ...

React does not allow _id to be used as a unique key

When I retrieve the categories from my allProducts array fetched from the database using redux-toolkit, I filter and then slice the array for pagination before mapping over it. However, I keep encountering a warning: Each child in a list should have a un ...

Encountering a "No exported member" error while attempting to include & { session: Express.Session } in the MyContext type while following a tutorial on React, Express, and Typescript

Currently exploring a React, Express, and Typescript tutorial, which is still quite new to me. I am trying to grasp the concept of setting up custom types, and this is what I have so far. In my types.ts file: import { Request, Response } from "expres ...

Unable to locate the reference to 'Handlebars' in the code

I am currently attempting to implement handlebars in Typescript, but I encountered an error. /// <reference path="../../../jquery.d.ts" /> /// <reference path="../../../require.d.ts" /> My issue lies in referencing the handlebars definition f ...

The latest version of https-proxy-agent is now 3.0.0, however, the npm audit is still indicating that

After the fix was provided for the NPM package https-proxy-agent on October 18, 2019, upgrading to the latest version still resulted in 6 high vulnerabilities being displayed in the audit warning. Even after running npm audit fix or npm audit fix --force ...

What is the best way to disable a submit button based on form validity in Angular 4 with ng-content?

Include a form component that consists of an email field, password field, and submit button passed through ng-content. This allows the login form to display a 'Login' button and the register form to display a 'Register' button. Here is ...

How to effectively filter a JSON array using multiple keys?

I need help filtering my JSON data by finding the objects with key 'status' equal to 'p' within the lease array. I attempted to use the following function, but it did not achieve the desired result: myActiveContractItems.filter((myActiv ...

Ways to conceal a component based on a specific condition?

In my Angular 8 application, I need to dynamically hide a component based on a specific condition. The condition I want to check is: "status === EcheqSubmissionStatus.EXPIRED" Initially, I attempted the following approach: EcheqProcessComponent templat ...

Issue with ngx-bootstrap custom typeahead feature malfunctioning

I'm facing an issue while trying to develop a customized typeahead feature that is supposed to search my API every time the user inputs something, but it's not functioning as expected. The autocomplete() function isn't even getting accessed. ...

The functionality of Angular 5 reactive form valueChanges is not functioning correctly

I am currently working with a form inside a service: this.settingsForm = this.formBuilder.group({ names: this.formBuilder.array([]), globalIDs: this.formBuilder.array([]), topics: this.formBuilder.array([]), emails: thi ...

ng2-dragula error: issues with setting options and dropping version

It seems that version 1.5.0 supports this.dragulaService.setOptions, while version 2.1.1 does not, and vice versa with this.dragulaService.drop subscribe where version 2.1.1 supports it but 1.5.0 does not. Check out the Stackblitz Fork for version 1.5.0 ...

Personalize the tooltip on ngx-charts heat map using custom tooltipTemplate

My attempt to personalize the tooltip of ngx-charts-heat-map led me to this code snippet: <ng-template #tooltipTemplate let-item="item"> <h1> {{getFlag(item.name)}} </h1> <h2>{{item.name}}: {{item.value}}</h2> </ ...

Confirm the data in each field of a form individually

I am facing an issue with a form that contains 7 fields. When I submit the form to the "register.php" page, it processes each field one by one and outputs the result as a whole. However, I need to validate the data using ajax, collect the output one by one ...

What is the reason behind the angular http client's inability to detect plain text responses?

When I make a call to httpClient.get, I notice in Fiddler that both the request and response headers have text/plain format. Request: Accept: application/json, text/plain, */* Response: Content-Type: text/plain; charset=utf-8 Even though I am returning a ...

Organizing string enum in Typescript and AngularJS - Tips and Tricks

In my Typescript file, I have defined an enum called PriorityLevel: enum PriorityLevel { High = <any>'High', Normal = <any>'Normal', Low = <any>'Low'} In the HTML section, I have the following code: <b ...

Using TypeScript with React: Automatically infer the prop type from a generic parameter

I've developed a component that retrieves data from an API and presents it in a table. There's a prop that enables the fetched value to be displayed differently within the table. Here's how I currently have the prop types set up: // T repres ...

Retrieving Data from Angular Component within a Directive

Currently, I am in the process of creating an "autocomplete" directive for a project. The aim is to have the directive query the API and present a list of results for selection. A component with a modal containing a simple input box has been set up. The ob ...

Child component not receiving disabled state from Angular 8 FormControl

In my code, there is a unique custom input that I have defined: <nivel-servico-slider formControlName="fornecedor_a"></nivel-servico-slider> This custom input has all the necessary properties as outlined in Angular's guide for c ...