8

I want to create a side menu in ionic 2 application where the page navigation component is placed in a external json file fetched with the help of menuService.getMenu function.

MY JSON structure:

"menu":[
        {
          "title":"Grid",
          "component":"GridPage"
        }
      ]

My Ts:

    this.menuService.getMenu().then((menu) => {
    this.menu = menu;
    });

    openPage(menu) {
      console.log("menu", menu.component);
      nav.setRoot(menu.component);
    }

Console log prints the string GridPage. I tried to convert using Type as Type(menu.component). But my result in console is a function with anonymous name. Someone please help me on getting the json string converted to component "Type" for navigation to work.

3
  • Looks like a dup of stackoverflow.com/questions/15338610/… Commented Feb 12, 2016 at 7:27
  • No. I want GridPage (menu.component) to get loaded when nav.setRoot is called. Since it is type of string, i am getting error. Commented Feb 12, 2016 at 8:36
  • I see, you need the type, not an instance. Commented Feb 12, 2016 at 8:37

2 Answers 2

12

I guess there is a way to get the type of a class by string but I don't know (I don't use TS). A simple workaround would be to

create a map from string to type

classes = {
  'MyClass1': MyClass1,
  'MyClass2': MyClass2,
  'Grid': Grid
}

and then just look the types up

class['Grid']

The disadvantage is that you need to know all supported classes in advance.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! Got me out of a bind. This should probably be the accepted answer.
6

I don't know Angular 2 in depth, but in a well structured application it is straightforward and feasible to get a Type using a string, if you know the fully qualified name of the given Type:

let typeName = "GridPage";
let ComponentType = MyApp.Components[typeName];

If you are getting the following type error:

Index signature of object type implicitly has an 'any' type.

... then you will need to type cast the preceding namespace (object). I prefer asserting to any in this case, as it's shorter than defining an inline interface for a string-based index signature, and you effectively don't lose any type-safety:

let ComponentType = (MyApp.Components as any)[typeName];

Additionally, this approach also works perfectly with modules:

import * as Components from "./components";

let ComponentType = (Components as any)[typeName];

12 Comments

Hi @John White. i am getting "cannot read property 'GridPage' of undefined error" on using var check = (<any>this.app.Components)[typevar]; Kindly help
@Aish123 It means that this.app.Components is undefined. This is usually caused by file ordering issues if you compile into a single output file. If you are compiling into a single output file, try specifying reference paths for the compiler to know the correct file order. The error you are getting is not specific to getting types from strings.
I am not sure whether the command in supported in angular2 typescript. i am getting syntax error in ts. File order does not matter in my case as i am importing all my files on initializing my app.
@JoseA This answer is more than a year old, nowadays it's preferred to use obj as Type instead (because <Type>obj is ambiguous in .tsx files). I've edited the answer accordingly.
@JoseA It would be simply (document.getElementById('my-id').getAttribute(‌​'custom-attribute') as any) as MyType, or document... as any as MyType.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.