1

I am working with Ian Li's Raphael SketchPad, and am having some trouble saving a drawing.

Upon changes on my sketchpad an object with id data is supposed to get updated, I placed a console log "changed" just to check. What happens is that upon loading the screen I see the console log message, and I don't see it again when changes are made.

How do I make the console.log run only after changes are made? Here is the extended code for the template I am using: https://gist.github.com/benbakhshi/5143484

<script type="text/javascript">
   var sketchpad = Raphael.sketchpad("editor", {
      height: 260,
      width: 260,
      editing: true // true is default
   });

   // When the sketchpad changes, update the input field.
   sketchpad.change(function() {
      $("#data").val(sketchpad.json());
      console.log("changed");
   });
</script>
Benjamin Bakhshi
  • 663
  • 2
  • 9
  • 22

1 Answers1

3

The problem looks like you're trying to console.log without a guarantee that the .json call has actually finished. Instead, try hooking to the change event of #Data to perform the logging. This will guarantee that the .json call has finished before logging.

Something like:

var sketchpad = Raphael.sketchpad("editor", {
  height: 260,
  width: 260,
  editing: true // true is default
});

$("#data").change(function () {
    console.log("changed");
});

// When the sketchpad changes, update the input field.
sketchpad.change(function() {
  $("#data").val(sketchpad.json()).change();
});
Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
  • How exactly do you think async operations work in javascript? If `sketchpad.json()` were async, it would need to return a promise (which I guarantee, `.val()` is not equipped to deal with) or receive a callback (we can see it doesn't). – Frances McMullin Mar 12 '13 at 14:57
  • That still didn't fix my issue. What I found strange is source code says to run `sketchpad.change(function() { $("#data").val(sketchpad.json()); });` although the input whose value is being updated has no ID, only name. I have tested my input with name,id & class, with #data & .data, together, and separately, but no results. – Benjamin Bakhshi Mar 12 '13 at 15:00
  • @DavidMcMullin `.val()` can receive a callback, just not an asynchronous one :) – Ian Mar 12 '13 at 15:03
  • 2
    @BenjaminBakhshi see my comment on your question, remove the space between `input` and `#data` or just use `#data` on its own. – Frances McMullin Mar 12 '13 at 15:04
  • 2
    @BenjaminBakhshi Did you try `$("[name='data']")`? – Mathew Thompson Mar 12 '13 at 15:04
  • @mattytommo, yes. No luck. – Benjamin Bakhshi Mar 12 '13 at 15:11
  • @Ian, that doesn't make a lot of sense. Assuming we are talking about the same function, `.val()` can receive a value (when I say receive, I am always referring to function params), if it received a callback (i.e., a function) it would probably just call `toString` on it, or error out. Which is still all irrelevant, because `sketchpad.json` would need to receive the callback, (which it clearly doesn't, having an empty param list), *not* `.val`. @BenjaminBakhshi, are you seeing any errors on the console? Have you tried removing all the other code to try and just get the change working? – Frances McMullin Mar 12 '13 at 15:39
  • 1
    @DavidMcMullin `val` can receive a callback, see the overload that takes a function here http://api.jquery.com/val/ – Mathew Thompson Mar 12 '13 at 15:40
  • @DavidMcMullin Sure it makes sense. http://api.jquery.com/val/#val-functionindex--value – Ian Mar 12 '13 at 15:40
  • @mattytommo , that's actually pretty cool, thanks for pointing it out. But it's still fairly irrelevant - the console.log is definitely executing after the call to `sketchpad.json()`. – Frances McMullin Mar 12 '13 at 15:45
  • @DavidMcMullin It's relevant for the fact that I mentioned that `.val()` accepts a callback, just not an async (deferred) one, meaning it requires a `return` statement – Ian Mar 12 '13 at 15:51
  • @Ian, Yes, you were absolutely correct, but this answer still doesn't solve the problem, and IMO introduces some confusion... – Frances McMullin Mar 12 '13 at 15:55
  • @DavidMcMullin Haha you're probably right about the answer, I have no idea what the `.json()` call does. I was just trying to point out the `val` "callback" availability. I think your original suggestion to use `$("#data")` (`$("input#data")`) is a possible solution, nonetheless correct – Ian Mar 12 '13 at 15:57