17 Replies Latest reply on Sep 4, 2007 7:21 PM by bitwyse

    Can you create an object from a string

    bitwyse Level 1
      I have been working on creating a dynamic form, creating the form items from an xml file. I am getting very close to conquering this task. I will share it when it's complete.

      However, I am stuck at the moment trying to create an object from a string. For example, if the xml item is an HBox I want to create an HBox. Like this: parentObject = new arrayOfFormItems[ index ]..type ()

      This isn't working. First, is this possible using some syntax I am unaware of in Flex? I don't want to use a large if or case statement if possible.

      Thanks in advance for your help!
        • 1. Can you create an object from a string
          dimival Level 1
          Check the Class documentation here:
          http://livedocs.adobe.com/flex/201/langref/Class.html

          There's a couple of good examples there of how you can create new instances of objects by using a Class variable, i don't know if there's a way to cast from String to Class, but if you can somehow achieve this, you could easily create new instances of objects.

          I guess a simple cast from String to Class will be pointless but you can try it out.

          Hope anything of this helps you out
          • 2. Re: Can you create an object from a string
            bitwyse Level 1
            I'm afraid I don't see how to use that code. Could be I just don't understand it maybe. I was hoping there was a simple way using some notation to create objects simply based on the value of a variable.
            • 3. Re: Can you create an object from a string
              dimival Level 1
              You can create a new object by doing this:

              var myClass : Class; // a class variable
              var myObj : Object; //an object variable
              myClass = Button; //we set the class to the Button class
              myObj = new myClass(); // a.k.a myObj = new Button();

              I have a custom component that has a public class variables and i can do something like this:

              var myExample : CustomComponent;
              myExample.classVariable = mx.controls.Button;
              var myButton : Button = new myExample();

              And that creates a new button component, as you can see i set the name of the Class that i intend to create, so if you could cast a String to a Class type then you could create new items dynamically.
              • 4. Re: Can you create an object from a string
                bitwyse Level 1
                I sort of understand what your doing, I guess I'm a bit slow on this concept. I'm still a bit unclear though how to implement your example based on values from my xml file. Here is a sample of my xml:
                <form>
                <formItem id="Subject">
                <label>Subject</label>
                <type>TextInput</type>
                </formItem>

                <formItem id="ShortDescription">
                <label>Short Description</label>
                <type>TextInput</type>
                </formItem>
                </form>

                Here is a snippet of the code
                // get all the items from the xml file
                arrayOfFormItems = new XMLListCollection( inputFile.formItem );

                // loop through all the items and create the different form items.
                for( var index : int = 0; index < arrayOfFormItems.length; index++ )
                {
                // her is where I'm stuck rather than put a big case statement for each type I want to dynamically create the types
                var myObject : Object = new arrayOfFormItems[index]..type() // this throws an error
                myObject.id = arrayOfFormItems[index]..id;
                parentObject.addChild( myObject );
                }
                • 5. Re: Can you create an object from a string
                  dimival Level 1
                  Ok let's focus on this line:

                  var myObject : Object = new arrayOfFormItems[index]..type()

                  You need a way to convert a String (arrayOfFormItems[index]) into a Class variable, you need it to be a Class variable in order to use the example i showed you. So in the end you need to have something like:

                  var myObject : Object = new classFromString();

                  where classFromString is the cast you made from arrayOfFormItems[index] to a Class variable
                  • 6. Re: Can you create an object from a string
                    bitwyse Level 1
                    OK, I see what your saying now. It seems to me it would be less code to use a switch statement I suppose since they both are not really dynamic so to speak.

                    I'll have to ponder the two a bit . . .

                    Thanks for shedding the light on this for me. . .
                    • 7. Re: Can you create an object from a string
                      dimival Level 1
                      I didn't quite get your last post but i get the impression you said the method i showed you is not dynamic at all, well if that is indeed your impression then you are still a bit confused, the example i showed you is completely dynamic as explained in the url i sent you, because the decision about which class to instantiate is decided on runtime.

                      I really don't see where is your comparison point between this and a switch statement, the switch statement means a lot more of code in your application.

                      So anyways, good luck solving this issue
                      • 8. Re: Can you create an object from a string
                        Senor_Roberto Level 1
                        Check out flash.utils.getDefinitionByName.

                        It will create you a Class object from a String parameter. You can then instantiate that new class.
                        I imagine like this (I haven't checked the syntax, just typing it in...):

                        var hboxClass:Class = flash.utils.getDefinitionByName("mx.containers.HBox") as Class;
                        var anHboxInstance:HBox = HBox(new hboxClass());

                        Or something similar...


                        • 9. Re: Can you create an object from a string
                          bitwyse Level 1
                          That was a whole lot closer to what I have been looking for. Unfortunately, still doesn't quite work as one would think. Here is my code that sort of works . . .
                          var tempStr : String = arrayOfFormItems[index]..type;
                          parentClass = getDefinitionByName( tempStr ) as Class;
                          parentObject = new parentClass();
                          addChild( parentObject ); <<== This does not work. It throws an error
                          1118: Implicit coercion of a value with static type Object to a possibly unrelated type flash.display:DisplayObject.
                          I guess you just can't do true dynamic object creation. I also found some documentation in order to get this to work you have to instantiate each object type once somewhere in your code. So in my mxml I had to create an hbox, vbox, textinput etc. and made them invisible.

                          I think I'll just use the switch statement for now to create the various types that I know I'll need. :-(
                          • 10. Re: Can you create an object from a string
                            Senor_Roberto Level 1
                            Are your types correct?

                            try:

                            addChild(DisplayObject(parentObject));
                            • 11. Can you create an object from a string
                              dimival Level 1
                              Roberto is right, you need to cast your object to a DisplayObject. It has nothing to do to what you said about having elements in the mxml, you really need to read carefully the documentation.

                              The addChild method signature is the following: public function addChild(child: DisplayObject):DisplayObject

                              So as you can see you NEED a DisplayObject in order to use the addChild method, just do what Roberto said, cast it to a DisplayObject and it should work.

                              By the way Roberto, great for telling how to obtain a Class from a String, i was clueless about that part
                              • 12. Re: Can you create an object from a string
                                bitwyse Level 1
                                Thank you very much. Indeed that did solve the one problem. I missed the casting as a Display Object. That is awesome!

                                I do still however, have to instantiate one of every item I want to dynamically create or I get the following error when I try to create a dynamic object that I have not instantiated before.
                                ReferenceError: Error #1065: Variable HBox is not defined.
                                at global/flash.utils::getDefinitionByName()
                                at MyForm/buildForm()
                                at DynamicForm/::onComplete()
                                at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
                                at flash.events::EventDispatcher/dispatchEvent()
                                at flash.net::URLLoader/flash.net:URLLoader::onComplete()

                                I read that you have no choice but to instantiate one of each type to force the linker to link the code for that class into the .swf. Unless you know another way to force it.

                                This is what I have in my Application mxml to get it to work:
                                <mx:HBox>
                                <mx:Text visible="false"/>
                                <mx:TextArea visible="false"/>
                                <mx:TextInput visible="false"/>
                                <mx:DateField visible="false"/>
                                </mx:HBox>

                                And those are the types I'm using to test with. . . I will have to add all the others I want to use as well . . .
                                • 13. Can you create an object from a string
                                  dimival Level 1
                                  Can you post the code where you create the Hbox using first the getDefinitionByName method, then the new operator and finally adding it to the displaylist with the addChild method?
                                  • 14. Re: Can you create an object from a string
                                    bitwyse Level 1
                                    Here is the code. Like I said it works, I just have to instantiate an hbox or vbox somewhere in my code which I do in my mxml else I get that error .eferenceError: Error #1065: Variable HBox is not defined. . . .

                                    // loop through all the items and create the different form items.
                                    for( var index : int = 0; index < arrayOfFormItems.length; index++ )
                                    {
                                    if( arrayOfFormItems[index]..type.toLowerCase().indexOf( "box" ) >= 0 )
                                    {
                                    var tempStr : String = arrayOfFormItems[index]..type;
                                    parentClass = getDefinitionByName( tempStr ) as Class;
                                    parentObject = new parentClass();
                                    addChild( DisplayObject( parentObject ) );
                                    }

                                    • 15. Re: Can you create an object from a string
                                      dimival Level 1
                                      What's the content of the arrayOfFormItems array? I mean the strings you are using for the getDefinitionByName method?
                                      • 16. Re: Can you create an object from a string
                                        Senor_Roberto Level 1
                                        In the 'type' element of your XML definition, make sure you're using the fully qualified path, i.e. mx.containers.HBox instead of just HBox.

                                        I just set up a test harness which does exactly what your code does, and guess what?

                                        HBox doesn't work!

                                        I can create mx.containers.Panel, mx.controls.Button etc. all of them dynamically, but if I do a mx.containers.HBox I get the error you're getting.

                                        Incredibly strange!

                                        The HBox constructor is no different from the other container objects. I can't see why the HBox in particular doesn't work.

                                        Further investigation required...
                                        • 17. Re: Can you create an object from a string
                                          bitwyse Level 1
                                          I am using the fully qualified name mx.containers.HBox.

                                          To make your code work instantiate an HBox in your mxml and make it invisible to force the class to be linked into your swf. That worked for me.