1

In a JS module in a Rails app I found this bit of code:

$body.on('ajax:success', '.js-comment-create', function(data, xhr, status) {
  var content = $(xhr.content), 
      $comment = $(content.comment);

and I wonder why xhr.content needs to be or should be wrappend in $()? I never paid attention to it as long as everything worked, but now, as I am debugging, I wonder why it is like this.

A quick test on the console shows that wrapping the xhr-Object return a JQuery object not a pure JS object. But what is the advantage of this in this particular situation where I just want to access data inside the object?

Edit: xhr.content is a JSON object, where the key comment holds a piece of html to replace some part of the DOM like so $(".aside ul.messages").prepend($comment);

Flip
  • 6,233
  • 7
  • 46
  • 75
  • You'll have to show what `xhr.content` looks like to get an answer to that question. – JJJ Feb 03 '17 at 11:05
  • @JJJ updated the question – Flip Feb 03 '17 at 11:08
  • The answer must be in how $comment is used later on – Christophe Roussy Feb 03 '17 at 11:20
  • @ Christophe Roussy: added that bit, too – Flip Feb 03 '17 at 11:24
  • 2
    *"`xhr.content` is a JSON object"* No, it's just an object. JSON is a *textual notation* for data exchange. [(More)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Feb 03 '17 at 11:43
  • The code frankly looks like a bug. `$()` will return a jQuery object. jQuery object's don't have a (documented) `comment` property. Seems like it should just be `var $comment = $(xhr.content.comment);` – T.J. Crowder Feb 03 '17 at 11:44
  • @T.J.Crowder: Quite possible that it is a bug. Thanks for your clarification. – Flip Feb 03 '17 at 11:48

1 Answers1

1

Based on the code you've quoted and the information you've provided, the answer to "Why is an object wrapped to become a jQuery object?" is: It looks like a bug. Not only is there no good reason to do that, doing so will make the code not work correctly.

The code should almost certainly be just:

$body.on('ajax:success', '.js-comment-create', function(data, xhr, status) {
  var content = xhr.content, 
      $comment = $(content.comment);

or even

$body.on('ajax:success', '.js-comment-create', function(data, xhr, status) {
  var $comment = $(xhr.content.comment);

...unless something else uses content later.

Here's what happens when you do what the code does:

var xhr = {
  content: {
    comment: "<p>I'm the comment</p>"
  }
};
var content = $(xhr.content),
    $comment = $(content.comment);
$comment.appendTo(document.body);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

vs. if you don't do the initial wrapping:

var xhr = {
  content: {
    comment: "<p>I'm the comment</p>"
  }
};
var content = xhr.content,
    $comment = $(content.comment);
$comment.appendTo(document.body);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875