HTMLDialog::show_modal content is blank when within HTTP::Request block

I’m pretty new to Ruby and Sketchup, so hopefully this is just something I’m messing up.

If I make a HTTP::Request and then on success show a HTMLDialog, the content is blank when using show_modal, but show works fine. Any idea what I’m doing wrong?

     def self.test_func
        request = Sketchup::Http::Request.new('http://sketchup.com', Sketchup::Http::GET)
        request.start do |request, response|
          puts response.status_code

          options = {
            :dialog_title => 'Test',
            :width => 500,
            :height => 400,
            :style => UI::HtmlDialog::STYLE_DIALOG
          }
          dialog = UI::HtmlDialog.new(options)
          dialog.set_url('http://google.com')
          dialog.center
          dialog.show_modal
        end
      end

show_modal pauses the execution of the code until it is closed. You can add a puts statement after show_modal and it wont be printed until the dialog is closed. I’m not sure though how this affects set_url.

@tom10

Try the following:

# test_func
# test_func modal: true
def self.test_func(modal: false)
  Sketchup::Http::Request.new('http://sketchup.com', Sketchup::Http::GET)
    .start do |req, resp|
      puts "resp.status_code #{resp.status_code}, modal #{modal}"

      options = {
        dialog_title: 'Test', width: 500, height: 400,
        style: UI::HtmlDialog::STYLE_DIALOG
      }
      dialog = UI::HtmlDialog.new options
      dialog.set_url 'http://google.com'
      dialog.center
      if modal
        dialog.show_modal
      else
        dialog.show
      end
      answer = UI.messagebox 'In request start', MB_OK
    end
end

First, run it with test_func. Notice that the UI.messagebox appears, but the HtmlDialog is not loaded/rendered yet. Once you close the UI.messagebox, the block and the method call complete, and the HtmlDialog shows google.

Then, run it with test_func modal: true. Since the HtmlDialog is shown modal, the UI.messagebox doesn’t appear. This also means that the block passed to Sketchup::Http::Request#start hasn’t completed, so the method hasn’t finished either.

So, what’s happening is that the HtmlDialog only processes things when the ruby code has finished. By placing a modal dialog inside a block used by a method, you’re stopping the code from finishing.

JFYI –

  1. It’s not common for UI code (or any significant code) to be placed in an HTTP request. One gets the request.body and ‘moves on’…

  2. I was introduced to Ruby via SketchUp about ten years ago, but I’ve been coding for decades. For new programmers, dialogs are messy, as they involve issues like the one here, but also using callbacks, etc.

  3. I changed the style of some of your code, how you write it is your choice.

That is what I would like to do. The Http::Request is async, so I can’t figure out how to get the token without yielding the result to function that opens the dialog. Again, I’ve been only working in Ruby a few days, so excuse my inexperience with parts of the language.

What I’m doing is making a request for an access token, once I have the token then I want to pop up the dialog. I would like to do something like the following, but we return from the function before access_token has a value.

def self.get_token
...
    access_token = nil
    request.start do |request, response|
      resultJson = {}
      if response.status_code == 200 && !response.body.nil?
        resultJson = JSON.parse(response.body)

        File.write(tokenFile, resultJson['access_token'])
      end

      access_token = resultJson['access_token']
    end

    return access_token
end

It looks like using Net::HTTP::Post, instead of the Sketchup:: version gets me what I want, since it is synchronous.