• Login
sketchucation logo sketchucation
  • Login
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

Webdialog - trouble passing array from JS to Ruby

Scheduled Pinned Locked Moved Developers' Forum
12 Posts 4 Posters 912 Views 4 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    rvs1977
    last edited by 19 Jun 2012, 20:09

    hi!

    I have a problem passing array from Webdialg (Javascript) to Ruby.

    Htmlfile.html

    
    <script>
    var layer_array = [108,190,95];
    query = 'skp;get_array@' + layer_array;
    window.location.href = query;
    </script>
    
    

    Rubyfile.rb

    
    my_dialog.add_action_callback("get_array") do |web_dialog,yv_array|
    UI.messagebox "YV_array from callback action; " + yv_array
    end
    
    

    In the html/js file its possible to do like this:
    alert("first item: " + layer_array[0]);
    => Output: "first item: 108"

    Or if I do like this:
    alert("all items: " + layer_array);
    => Output: "all items: 108,190,95"

    Every things work fine!

    But, when its send back to ruby the trouble starts:
    If I write:
    UI.messagebox ("first item: " + layer_array[0])
    => Output: "first item: 57"

    But if I write:
    UI.messagebox ("all items: " + layer_array)
    => Output: "all items: 108,190,95"
    Here it seems to work???

    My guess is when its send from JS to Ruby it goes from being an array to be a string?

    Anyone know how to overcome this problem?

    -Rasmus


    Get a Ruby

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 19 Jun 2012, 20:44

      First of all... using UI.messagebox as a debugging tool is a bad idea.
      They often fail silently, if the message argument is not correct, or there are Type mismatches in the expression.

      Get in the habit on opening the Ruby Console, and using puts() to output debug strings.

      And you can use the .to_s() or .inspect() methods to be sure the output is String compatible:

      my_dialog.add_action_callback("get_array") do |web_dialog,yv_array|
        puts "YV_array from callback action; " + yv_array.inspect
      end
      

      Also the double-quoted String parameter replacement notation, #{*expression*}, has built-in text conversion for many Ruby base classes.

      So this may also work:

      my_dialog.add_action_callback("get_array") do |web_dialog,yv_array|
        puts "YV_array from callback action; #{yv_array}"
      end
      

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • D Offline
        Dan Rathbun
        last edited by 19 Jun 2012, 20:52

        @aerilius said:

        If I am right the webdialog returns a string, for example %(#000000)["[1,2,3]"]
        ...
        Or you eval the array ...

        Yup you are correct, and eval() is the simplest way.. provided that on the Js side, you build the strings so Ruby's eval() can read them.

        @unknownuser said:

        (https://developers.google.com/sketchup/docs/ourdoc/webdialog#add_action_callback )":1lvv2jxf]Your JavaScript in the webdialog will invoke the callback method with a string representing arguments to the callback method.

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dan Rathbun
          last edited by 19 Jun 2012, 20:58

          Make sure to read by Thomas Thomassen (ThomThom)

          PDF download: WebDialogs - The Lost Manual — R1 09 November 2009

          SCF Forum Post: WebDialogs - The Lost Manual — R1 09 November 2009

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • A Offline
            Aerilius
            last edited by 19 Jun 2012, 21:07

            The webdialog returns a string, for example %(#000000)["[1,2,3]"]. In Ruby, you always need to have a clear idea what type your value has. In JavaScript, you can mix incompatible types hoping that it will convert it and work as expected, but not in Ruby.
            Don't miss to read the Ruby Newbies Getting Started Guide

            If you apply an index to a string, you get the character code of the character at that index, example
            "string"[0] = 115 # corresponds to 's'

            When you later added a string + the arraystring, you got the expected result because both were strings. You can't add an array to a string, because it would give:
            Error: #<TypeError: (eval):151:in+': can't convert Array into String>The **+** method is not defined for different types. It exists separately for Numeric, for [Strings](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html#String._pl) and for [Arrays](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_array.html#Array._pl), and if you have different types, you have to convert them into the same so that you can use one of the methods for it (either with array.to_sor array.inspect`).

            You could either parse the string into an array for example

            @yv_width_array_rs = yv_width_rs[1..-2].split(",")
            

            which returns an array of strings.
            If it should be floats (or integers) then you loop over the resulting array with collect and convert each string of a float into a float with [to_f](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html#String.to_f):

            @yv_width_array_rs = yv_width_rs.scan(/\d+/).collect{|d| d.to_f} # or d.to_i
            

            Or you eval the array

            begin
              @yv_width_array_rs = eval(yv_width_rs)
            rescue
              @yv_width_array_rs = []
            end
            

            which you should absolutely avoid if there is an alternative way.

            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by 19 Jun 2012, 21:19

              When you experience trouble with Ruby <-> JavaScript check the compiled string you send backwards and forwards. You will when quickly see syntax errors.

              Thomas Thomassen — SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • R Offline
                rvs1977
                last edited by 20 Jun 2012, 04:53

                Thank you all!! Now I have something to try out. 😄


                Get a Ruby

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Dan Rathbun
                  last edited by 20 Jun 2012, 05:30

                  @aerilius said:

                  Or you eval the array

                  begin
                  >   @yv_width_array_rs = eval(yv_width_rs)
                  > rescue
                  >   @yv_width_array_rs = []
                  > end
                  

                  Here's a good place to show, how to use the rescue keyword, in modifier position (and save 4 lines of code.)

                  @yv_width_array_rs = eval(yv_width_rs) rescue []

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • R Offline
                    rvs1977
                    last edited by 22 Jun 2012, 13:30

                    Aerilius, Im a little impressed.

                    When you quote my code, you use different variable-names than the ones from my example.
                    The funny thing is, the variable-names you use is the one I actually use on my own computer, before I started to look at arrays... Are you psychic or something?? 😄


                    Get a Ruby

                    1 Reply Last reply Reply Quote 0
                    • A Offline
                      Aerilius
                      last edited by 22 Jun 2012, 16:55

                      I'm not psychic but rather impressed/surprised myself. That are the variable names that you posted 😒 and after submitting my response, you had modified/improved the original question that I didn't recognize it anymore 😄

                      1 Reply Last reply Reply Quote 0
                      • R Offline
                        rvs1977
                        last edited by 22 Jun 2012, 20:57

                        ah ok 😄

                        Anyway, it finally works with this "simple" solution:

                        
                        my_dialog.add_action_callback("get_array") do |web_dialog,yv_array|
                        @YV_array = yv_array.scan(/\d+/).collect {|d| d.to_i}
                        end
                        
                        

                        I wonder why the eval-rescue solution has to be avoided? Is it slow?

                        Thanks to all of you. - Aerilius, Dan, Thomthom


                        Gratias Ad Omnes


                        Get a Ruby

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          Dan Rathbun
                          last edited by 22 Jun 2012, 21:34

                          @rvs1977 said:

                          I wonder why the eval-rescue solution has to be avoided? Is it slow?

                          ALL String operations in Ruby 1.8.x are slow.

                          eval() is the Ruby code parser.. so it is a very large method (actually a C-side function.)

                          But I cannot see it being slower than the 2 iterator methods you are using, in addition to the type converter.

                          But it works... and you understand how it works. If speed is not an issue, then go with it ...

                          👍

                          Also if you KNEW each numeric was separated by a "," then you also do:

                          @YV_array = yv_array.split(',').map{|i| i.to_i}

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          1 / 1
                          • First post
                            1/12
                            Last post
                          Buy SketchPlus
                          Buy SUbD
                          Buy WrapR
                          Buy eBook
                          Buy Modelur
                          Buy Vertex Tools
                          Buy SketchCuisine
                          Buy FormFonts

                          Advertisement