Dynamically get class members names and values using Typescript or javascript
Dynamically get class members names and values using Typescript or javascript
I'm pretty new with these languages and I'm sure it's not so complicated but could not find how to walk through class instance variables dynamically.
I'm trying to display instance's variables in a table using Angular. I'd like to write a single function that will work with any class.
Let's say I have a workbook class:
export class workbookEntity
public name: string;
public creationDate: string;
constructor()
this.name = 'my work book name';
this.creationDate = '2018/01/26';
And let's say I want to get the names and values of the variables of an instance of this class in another class' function:
export class showClassComponent
// some code here
whenSubmitedInHtmlForm(className: string): void
// do something to walk through instance
// with className parameter = 'workbookEntity'
// more code there
How would you walk through the instance to get each variable's name and value to get something like this?
[
name: 'name',
value: 'my work book name'
,
name: 'creationDate',
value: '2018/01/26'
]
What are you really trying to do?
– Sébastien
Jan 26 '18 at 20:04
Yea, create a service with a Behavior Subject that is updated by a given instance. Then just subscribe to that Subject from the component that will utilize the info.
– David Aguirre
Jan 26 '18 at 20:29
@Sébastien: I'm trying to display different objects in a cdk table. The table has 2 columns: Variable & Value. The list of the objects names is displayed. Each time the user select an object name, all instances and their variables and values are displayed in the 2 columns of the table.I don't want to write a cdk source for each type of objects. I'd like to have a single function that will work with any object.
– l_r
Jan 28 '18 at 17:08
2 Answers
2
There's no concept of reflection, so much in Typescript, so you can't neccessarily do a type lookup. But you might be able to do something along the lines of...
export class showClassComponent
var classes = [ name: 'workBookEntity', value: new WorkBookEntity() ]
whenSubmitedInHtmlForm(className: string): void
let c = classes.filter(class => class.name == className)[0];
if(c)
let ret = ;
for (var key in c)
if (c.hasOwnProperty(key))
ret.push( name: key, value: c[key] );
return ret;
// more code there
Maybe also helpful: stackoverflow.com/questions/40636292/…
– Barry Tormey
Jan 26 '18 at 20:14
I was hoping something more direct was possible. Nice hack. It did the trick.
– l_r
Jan 28 '18 at 17:22
this returns values only if the property is initialized
– Nitin Sawant
Jan 31 at 10:15
If you want to be able to retain accurate type information, you can create a pick utility function and then just import it into your class module wherever you need to use it.
let workBook = new WorkbookEntity();
export function pick<T, K extends keyof T>(obj: T, keys: K): Pick<T, K>
let newObj = as Pick<T, K>;
for (const key of keys)
newObj[key] = obj[key];
return newObj;
console.log(pick(workBook, ['name', 'creationDate']));
// log: name: 'my work book name', creationDate: '2018/01/26'
Then you can import the first function into another utility function if you to be able to handle multiple objects.
export function pickObjects<T extends object, K extends keyof T>
(objects: T, keys: K): Pick<T, K>
return objects.reduce((result, obj) => [...result, pick(obj, keys)], );
let workbooks = pickObjects([workBook, workBook2], ['name']);
workbooks[0].name // this exists
workbooks[0].age // Typescript error.
The editor will show that age doesn't exist since we didn't pick it
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy
You should create a service for work like this. Otherwise you would need to inject the component to get access to its variables.
– David Aguirre
Jan 26 '18 at 19:57