Lelio Faieta
Lelio Faieta

Reputation: 6663

handle data returned from an AJAX call

I have the following script to load an HTML page that is generated from a node.js server:

    (function nodeLoader(){
        $.ajax({
            url: "http://oclock.dyndns.org:8000",
            method: "get",
            data: {hk: hk },
            success: function(data){
                var visibile = $("div.scheda:visible").attr("id");
                $('.scheda').hide('fast',function(){$('#99').html(data).show();});
                setTimeout( function(){
                    //devo prendere id del messaggio visualizzato e settarlo a letto
                    $('.scheda').hide('fast',function(){$('#'+visibile).show().html(data);});
                },30000 );
            }
        });
    })();

the page loaded is the following:

<div id="container"></div>

<script>
// create a new websocket
var socket = io.connect('http://oclock.dyndns.org:8000');
// on message received we print all the data inside the #container div
socket.on('notification', function (data) {
    var msgs = '';
    $.each(data.flashmsgs,function(index,flashmsg){
        msgs += "<div>"
        msgs += "<h3>Messaggio inviato da " + flashmsg.created_by + "</h3><br>";
        msgs += "<p>" + flashmsg.testo + "</p></div>";
    });
    $('#container').html(msgs);
});
</script>

What I am trying to get is to add to nodeLoader a if (in success function) that says: if #container contains data (the node.js server is fetching something) then do hide and show. How can I do this? How to drill down data variable? The only idea I got is to change the node.js server to serve a json array instead of the page but I'd like not to rewrite the server by now.

Upvotes: 1

Views: 244

Answers (1)

Andrew Dunai
Andrew Dunai

Reputation: 3129

I had a similar problem and it's really very painful to find a flexible way of passing some metadata together with HTML. Of course, the best way is using JSON, but in case you cannot do such changes, there are still few possible solutions to accomplish this without rewriting a lot of code.

The first one is to include some metadata in a comment node, for example:

<!--META:{"count":3}-->
<ul>
    <li>Message 1</li>
    <li>Message 2</li>
    <li>Message 3</li>
</ul>

The second one is to pass <script> tag with some code while declaring some callback, e. g. dataLoaded before inserting the HTML into document. Keep in mind that this method is potentially unsafe:

<ul>
    <li>Message 1</li>
    <li>Message 2</li>
    <li>Message 3</li>
</ul>
<script type="text/javascript">dataLoaded({"count":3})</script>

The third one is to manually manipulate data, however it is not a very good practice to make JavaScript code depend on HTML DOM structure very much.

$.ajax({
    ...
    success: function(data) {
        var count = $(data).find('li').length; // count == 3
    }
});

Finally, similar to the first way, you can just use some hidden nodes:

<input type="hidden" name="count" value="3" />
<ul>
    <li>Message 1</li>
    <li>Message 2</li>
    <li>Message 3</li>
</ul>

...or even use data-* attributes:

<ul class="messages" data-count="3"> <!-- NOTE: Don't forget to cast attribute value to Integer in JavaScript -->
    <li>Message 1</li>
    <li>Message 2</li>
    <li>Message 3</li>
</ul>

I hope this helps.

Upvotes: 1

Related Questions