These are chat archives for opal/opal

17th
Mar 2017
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:39
Hi @catmando, what i was trying to do was read a csv file in a hyper-react component and store in local state, but i've basically written most of it in JS inside the ruby app, the issue that i'm having is running the ruby proc when for the onload callback
Mitch VanDuyn
@catmando
Mar 17 2017 01:41
@bradder555 a little context please... when you say read... are you reading it off the clients disk?... onload of what the page? the file? can you share a code slice?
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:43
i considered writing the react component in js and importing into opal so i started writing a proof of concept in pure JS react

<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script>
</head>
<body>
<div id="cont"></div>
<script>

var el = React.createElement
var co = React.Component

  class DisplayText extends co
  {
    constructor(props)
    {
      super(props);
    }

    componentDidUpdate(prvProps, prvState)
    {
      console.log("component did update")
      console.log(prvProps) 
      console.log(this.state)
    }

    render()
    {
      console.log(this.props)
      if (this.props.text != "")
      {
        return el("p", null, `${this.props.text}`)
      }
      return null
    }
  }


  class FileInput extends co
  {
    constructor(props)
    {
      super(props);
      this.state = 
      {
        count: 54,
        text: ""
      }
      this.file_changed = this.file_changed.bind(this)
    }

    file_changed() 
    {
      var file = document.getElementById("rand_id").files[0]
      var r = new FileReader()
      var self = this
      r.onload = function()
      {
        self.setState({text:this.result})
      }
      r.readAsText(file)
    }

    componentDidUpdate(prvProps, prvState)
    {
      console.log("component did update")
      console.log(this.state)
      console.log(prvState)

    }

    render() 
    {
      return (
        el("div", null, 
        [
          el("div", null, `hello ${this.props.prop_1} ${this.state.count}`),
          el("input",{id:"rand_id", type: "file", onChange:this.file_changed},null),
          el(
            'titface',
            null,
            React.createElement(
              'div',
              { id: 'your_mum', style: {width:'50px', height: '100px'}},
              `hello ${this.state.count}`
            )
          ),
          el(DisplayText, {text:this.state.text}, null)
        ])
      )
    }
  }


  ReactDOM.render(el(FileInput, {prop_1:"darth vader"}, null), document.getElementById('cont'));

</script>
</body>
</html>
Mitch VanDuyn
@catmando
Mar 17 2017 01:44
reading...
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:44
so you can see, rand_id is <input> type file on change calls file_changed
i'll let you read, there's a bit of additional noise..
Mitch VanDuyn
@catmando
Mar 17 2017 01:46
okay so does this work?
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:46
yeah
no trouble
but achieving the same in opal is a headache
Mitch VanDuyn
@catmando
Mar 17 2017 01:47
gotcha... so you just want to get this converted over to pure ruby / hyperloop
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:47
this is my ruby
 10           label style:{width: "30em"} do
  9             input(id:state.input_id, type:"file", accept:params.file_extensions, style:{width: "100%"}).
  8             on(:change) do |e|
  7               reader = `new FileReader()`
  6
  5               #{reader}.onload =
  4               #function(){
  3               #var data = Papa.parse(this.result, {header:true}).data
  2               #var pp = JSON.stringify(data, null, 2)
  1               #}
35                i = Element.find("#" + state.input_id)
  1               $global.console.log(i)
  2               i.on(:change) do |ev|
  3                 puts ev
  4               end
  5               #var i = $("#" + #{state.input_id})[0]
  6               #{reader}.readAsText(i.files[0])
  7
  8            end # input change
  9           end # label
Mitch VanDuyn
@catmando
Mar 17 2017 01:47
(I realize that was your original question :-) just had to get some context ...)
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:48
sure, you can see where i've commented stuff out
Mitch VanDuyn
@catmando
Mar 17 2017 01:48
ahhh
I see the issue (I think)
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:48
so i was using the backticks, but the issue was on the callback
Mitch VanDuyn
@catmando
Mar 17 2017 01:49
you have (reasonably) assumed you can do i.on(:change) to define a callback (actually that is a good idea)
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:49
it has undergone a number of permutations and changes
Mitch VanDuyn
@catmando
Mar 17 2017 01:49
but adding .on(:xxx) handlers is a Hyperloop feature
but i is just a dom element
so you need something like this:
Element[i].on_load = lambda (...) { .... }
(I think that is the syntax)
I would put a debugger
just before you do the Element[i].on_load = ...
when it hits the breakpoint you can see the source generated and screw around in the console until it works
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:52
there has been plenty of screwing around lol
a more general question
Mitch VanDuyn
@catmando
Mar 17 2017 01:52
FYI i know this works as we do this in our code... @adamcreekroad is the guy that has done it
so the specific Opal question is how to attach a on_load handler using the Element jquery wrapper.
but I do like your idea that Hyperloop should add the .on feature to Element for consistency.
sorry the general question?
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:53

if i have

x = lambda {|y| state.state_to_update! y}

how would i run it in

`
jscallback = function(){
#{x}(event.file[0]) // I'm lost here!!
}
`
Mitch VanDuyn
@catmando
Mar 17 2017 01:54
first off
it will be state.state_to_update! y
you code looks right
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:55
i noticed that just before you mentioned
no way
lol
i'll give it a try
Mitch VanDuyn
@catmando
Mar 17 2017 01:58
fyi have to sign off now... I know some guys in europe are pretty active on the hyperloop chat room if you ask questions there you will probably get somebody to answer in a few hours... https://gitter.im/ruby-hyperloop/chat
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 01:58
thanks for that Mitch
i'll post in here and let you know how i go
Night
Ghost
@ghost~57bd5b1440f3a6eec0610e8d
Mar 17 2017 02:05
@catmando
I can't believe i spent all that time yesterday and it works!
thanks for that!
Here's what i ended up with:
       def reader_to_state(content)
         state.file_contents! content
       end

       def render
         div do
           label style:{width: "30em"} do
             input(id:state.input_id, type:"file", accept:params.file_extensions, style:{width: "100%"}).
             on(:change) do |e|
             temp = lambda {|x| reader_to_state(x)}
               `
               reader = new FileReader()
               reader.onload =
               function(){
                 var data = Papa.parse(this.result, {header:true}).data
                 var pp = JSON.stringify(data, null, 2)
                 #{temp}(pp)
               }

               var i = $("#" + #{state.input_id})[0]
               reader.readAsText(i.files[0])
               `
             end # input change
           end # label
         end # div
       end # render
i was at 90% there for most of yesterday! it seems odd that i couldn't use reader_to_state directly and had to wrap up in a local lambda, but it works i think i'll leave it for now
Mitch VanDuyn
@catmando
Mar 17 2017 02:09
I would think this would work too:
   def reader_to_state(content)
     state.file_contents! content
   end

   def render
     div do
       label style:{width: "30em"} do
         input(id:state.input_id, type:"file", accept:params.file_extensions, style:{width: "100%"}).
         on(:change) do |e|
         temp = lambda {|x| reader_to_state(x)}
           `
           reader = new FileReader()
           reader.onload =
           function(){
             var data = Papa.parse(this.result, {header:true}).data
             var pp = JSON.stringify(data, null, 2)
             #{state.file_contents!}(pp)
           }

           var i = $("#" + #{state.input_id})[0]
           reader.readAsText(i.files[0])
           `
         end # input change
       end # label
     end # div
   end # render
best tool I have found again is stick a debugger line just before and see what code is generated that usually gives good clues
but glad you worked it out