0

I'm trying to get a json response from a rails controller and insert it into a js function. I keep getting errors:

MY CONTROLLER

def live #users present or attendees view
    @presentation = Presentation.find(params[:secret])
    @countdown = @presentation.start - DateTime.now()


    #IF A PERSON IS A PRESENTER
    if @presentation.presenter.id == current_user.id
      @presenter = true
      require 'json'
      require 'net/http'
      require 'uri'

      uri = URI.parse('https://api.screenleap.com/v2/screen-shares')
      req = Net::HTTP::Post.new(uri.path, initheader = {'accountid' => 'APPID', 'authtoken' => 'MYTOKEN'}) #These are correct in actual code
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      res = http.request(req)

      @screenShareData = JSON.parse(res.body)

    #IF A PERSON IS AN ATTENDEE
    else
      @presenter = false
      @screenShareData = false
    end
  end

IN MY VIEW

<script>
  <script type="text/javascript" src="https://api.screenleap.com/js/screenleap.js"></script>

  window.onload = function() {
    var callbacks = {
      nativeDownloadStarting: [onNativeDownloadStartCallback],
      screenShareStarting: [onScreenShareStarting],
      appConnectionFailed: [onAppConnectionFailed],
      screenShareStartError: [onScreenShareStartError]
    };
    var screenShareData = <%= @screenShareData %>;
    var presenterAppType = 'NATIVE';

    screenleap.startSharing(presenterAppType, screenShareData, callbacks);
  };
</script>

In my view I also tried:

var screenShareData = <%= @screenShareData.to_s.html_safe %>;

In either case I seem to get one of two javascript errors. Either "Uncaught SyntaxError: Unexpected token &" or "Uncaught SyntaxError: Unexpected token =>"

My feeling is that it's somehow not translating the JSON the way the function expects it. Any idea how I might fix the issue?

4
  • isn't @screenShareData = JSON.parse(res.body) parsing the JSON data and storing as Hash? Either you do not parse it at all or convert it to JSON using .to_json method. Commented Mar 12, 2018 at 3:29
  • my feeling is that you're not getting a json response from your controller, try console.log(screenSharedData) to see what you got. Commented Mar 12, 2018 at 3:30
  • take a look at this : stackoverflow.com/questions/6404950/… Commented Mar 12, 2018 at 3:34
  • I tried not parsing it as well. To no avail. Also I am getting a json response because I can display it and all the data in the view as a string. I'll take a look at the question you linked, Taki, I think that is similar to the response below. Commented Mar 12, 2018 at 19:05

2 Answers 2

0

You can pass the rails JSON variable I got from the controller by modifying the variable in the view as below:

<%= @screenShareData.to_json.html_safe %>

After that, the screenleap.startSharing function accepted the data and worked. It should be noted that I also removed the "callbacks" variable, but I isolated the change in the "screenShareData" variable as the one that fixed the issue.

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

Comments

0

You can't use irb syntax in js code

var screenShareData = <%= @screenShareData %>;

There are a few options to achieve what you want:

  1. respond with json in your controller action and request it from client via ajax request

  2. render this data @screenShareData in any of html tags data-attribute and get it with jQuery or vanilla js methods

UPDATE: I was wrong about that and you can inject ruby code in js. Here is an answer to your question:

var screenShareData = JSON.parse("<%= j @screenShareData.to_json.html_safe %>")

Where j is an alias to escape_javascript.

There is also another way:

var screenShareData = <%= raw @screenShareData.to_json.html_safe %>

But I would not suggest that because:

  1. It might not work in some cases. If for example @screenShareData has special characters and such
  2. @screenShareData might have some code inside that will be executed in client browser

Also I suggest you to move api.screenleap.com request logic from controller action to service object.

What are you going to do if api.screenleap.com is unavailable or responds with an error?

Net::HTTP::Post is a blocking request means that if api.screenleap.com takes 5 seconds to respond then your client browser render will hold for 5 seconds. I suggest you do it async unless its desired behavior

You have different data formats in the same action response. If @presentation.presenter.id == current_user.id is true then its an array or an object. If false then its boolean. That's not cool

3 Comments

Thanks I'll give this a shot. Stay tuned... As for the messy formats, I haven't built out the situation where someone is accessing the page but not a presenter. So everything in the "else" is just a placeholder to avoid an "undefined variable" error, when I start to build it. It will not be its final form. Thanks again for your advice.
Your first statement is incorrect. You can use ERB in JS code.
@RyanFriedman thanks for pointing that out. I updated my answer

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.