angularclassnewable

Is it possible to pass a type to an Angular component that can 'newed'?


I am developing a generic dropdown component. If the user enters a value not in the list, I want to return a new object of the same type in the itemSelected event. I need to preserve the methods as well as the properties - so just creating a generic object won't work. This needs to work even if the list is empty so it won't work to do something like Object.create(this.list[0]);

My work-around so far is to just pass a reference object, which I CAN use with Object.create but this seems lame.

The following snippet shows what I'm trying to do. Is there a way to do this or a better way to do what I want? Thanks - Jon

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-generic-new',
  templateUrl: './generic-new.component.html',
  styleUrls: ['./generic-new.component.scss']
})
export class GenericNewComponent implements OnInit {
  ngOnInit(): void {}

  @Input() type:any 

  createNewType():any {
    // this is what I'm trying to do - but doesn't work
    return new this.type();
  }
}

Solution

  • Using Generics

    class container<T> {
        id: T;
        key: T;
        displayValue: T;
        type : T;        
    }
    //allows you to control the type, here we are allowing any, but could be person, address etc.
    let myContainer = new container<any>();
    myContainer.id = 0;
    myContainer.key = "UserEnteredKey";
    myContainer.displayValue = "UserEnteredDisplayValue;
    myContiner.type //allow access to anything or a specific class type.
    

    Not using generics.

    class container{
     id:number;
     key:number;
     displayValue:string;
     type:any;
    }
    let myContainer = new contaier();
    myContainer.number = 10;
    myContainer.key = "UserEnteredKey";
    myContainer.displayValue = "User Entered Display Value";
    myContainer.type = {key:myContainer.key, display: myContainer.displayValue, doSomething: function(){//do something here.}}
    

    Note that any of the values above can be computed instead of being static, for example IDs are usually computed.

     @Input() type:container
    
      createNewType():any {
        // this is what I'm trying to do - but doesn't work
        return
         let myContainer = new container<any>();
         myContainer.id = this.getNextID();
         myContainer.key = "UserEnteredKey";
         myContainer.displayValue = "UserEnteredDisplayValue;
         myContiner.type //allow access to anything or a specific class type.
    }
    

    Your form will need to expose all the properties the user needs to change via binding to this cass model.