Announcement

Collapse
No announcement yet.

DateTime boxing / unboxing problem

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    DateTime boxing / unboxing problem

    Hi

    I'm in the process of migrating from 15.7.0 to v16. I encountered a big problem along the way: In v15 all DateTime instances represented a pure JS Date object, which made it very intuititve and straightforward to databind DTO objects to third party JS controls (like DevExtreme scheduler etc.)

    In v16 there seems to be a wrapper around (almost?) every DateTime instance with a $boxed=true variable under the hood. Obviously, this type is no longer compatible with the JS Date, which destroys all my databinding scenarios that worked before. Could this be related to the change in ObjectLiteral behavior? Can I get the "old" Date behavior back?

    Your help is greatly appreciated

    Marco

    #2
    Hi,

    Can you demonstrate the problem with boxed DateTime? Just if you pass an object to external API then Bridge will unbox it automatically.

    Comment


      #3
      Hi Vladimir

      Thanks for your answer! It's difficult to reproduce this in Deck.NET as the boxing is not really visible there...

      Consider the following class
          [ObjectLiteral(ObjectCreateMode.Constructor)]
          public class Event
          {
              public DateTime Start { get; set; }
              public DateTime End { get; set; }
          }
      This literal class is NOT external, it's part of my application. I want to enforce filling it with JS-compatible dates, so that I can bind an array to an external scheduler control. Additional challenge: Reflection is also needed because I use my own dynamic databinding algorithm, so marking with [External] is not an option here.

      I suspect the problem is that the external scheduler's interface is not strongly typed. It just expects any JS object in the form of myEvent["startDate"], and so Bridge doesn't ever get to a point where it realizes that it has to unbox. That's why I really need to enforce unboxing in my own, reflectable code.

      Any thoughts? And also: Is there any article that elaborates on why the whole boxing/unboxing was introduced and which types are affected besides DateTime?

      Thanks,
      Marco

      Comment


        #4
        I managed to reproduce the problem in Deck:

        https://deck.net/39123d168c3a1c7df7132eacd5093068

        As you can see, the DateTime is never unboxed (otherwise the console would have to return "undefined"). You can play with the attributes on the Event class... nothing seems to change the boxing behavior.

        Comment


          #5
          Last but not least I found an ugly workaround, but that's almost as bad as writing native JS ;-)

          https://deck.net/18589acd19fc1ec56e5945d1932e7d2c

          I hope you can provide me with a clean way of enforcing an unbox or give me some bridge.json setting to turn it off all together...

          Comment


            #6
            Hi,

            When I said that Bridge automatically unbox object I meant that it occurs if pass object to external API (not that object should be from external API)
            Just see
            https://dev.deck.net/164dd01cb73bbc814b3bcc0e019f945f

            About your workaround, you don't need it, just cast object to required type and unboxed operation will be generated by Bridge
            DateTime dt = (DateTime)boxedVar;
            We are investigating the possibility to control compiler's behaviour (for example, avoid boxing/unboxing operations).
            Last edited by geoffrey.mcgill; 2017-08-22 @ 10:36 AM.

            Comment


              #7
              Hi Vladimir

              Thanks for your reply. I understand now what you mean, but this still leaves the problem unsolved of enforcing unboxed objects. There's no way any third party JS library will ever be able to interpret the boxed version of a DateTime, I'm sure you agree.

              So we urgently need a means to enforce unboxing. This could be something as simple as:
              [ObjectLiteral(ObjectCreateMode.Constructor, AlwaysUnbox=true)]
              public class Event
              {
                  public DateTime Start { get; set; }
                  public DateTime End { get; set; }
              }
              Hard casting like you suggested is usually not an option, because these objects are deserialized in some sort of property loop, and it's either unpractical to account for all possible unboxing scnearios manually, and sometimes it is just plain impossible.

              For example I'm using a custom JsonReviver and it creates boxed versions of DateTime without any ability to control this.

              Thanks for your help,
              Marco

              Comment


                #8
                Hi Marco,

                Bridge 16.2.0 has been released. Please update your project and let us know if you run into any issues.

                Hope this helps.

                Comment


                  #9
                  I forget to add, we're going to making some more improvements to the DateTime class in an upcoming 16.x release.

                  Comment


                    #10
                    Geoffrey, Vladminir, thanks so much for your help! It seems to all work again as of v16.2.

                    If I can do anything to help you guys in return, let me know.
                    Best regards
                    Marco

                    Comment

                    Working...
                    X