1

I have developed an application to write twitter search results as JSON objects to a results page as such:

for (Status tweet : tweets) {
    Map<String, String> tweetResult = new LinkedHashMap<String, String>();
    tweetResult.put("username", tweet.getUser().getScreenName());
    tweetResult.put("status", tweet.getText());
    tweetResult.put("date", tweet.getCreatedAt().toString());
    tweetResult.put("retweets", String.valueOf(tweet.getRetweetCount()));
    String resultJson = new Gson().toJson(tweetResult);
    response.getWriter().write(resultJson);
}

This is called with AJAX/JQuery in the following:

$(document).ready(function() {                                                                      
    $.getJSON('SearchServlet', function(list) {
        var table = $('#resultsTable');
        $.each(list, function(index, tweet) {
        $('<tr>').appendTo(table)
                .append($('<td>').text(tweet.username))
                .append($('<td>').text(tweet.status))
                .append($('<td>').text(tweet.date))
                .append($('<td>').text(tweet.retweets));
        });
    });
});

With the intention of populating a table with the results:

<body>
    <div id="wrapper">      
        <div id="contentArea">
            <div id="content">
                <h2>Results:</h2>
                <table id="resultsTable"></table>
            </div>
        </div>
    </div>
</body>

The GET call is working perfectly and the results show up in the firebug console without a problem, however they're not appearing on the actual document itself as intended. I've tried a number of different approaches to this (including the answers here and here ).

Example of the JSON output:

{"username":"Dineen_","status":"RT @TwitterAds: Learn how to put Twitter to work for your small business! Download our small biz guide now: https://t.co/gdnMMYLI","date":"Tue Feb 26 08:37:11 GMT 2013","retweets":"22"}

Thanks in advance.

Community
  • 1
  • 1
richardb
  • 33
  • 1
  • 6
  • 1
    It is better if you show the actual HTML result you are seeing – Alexander Feb 26 '13 at 18:02
  • 1
    @richardb If you do `console.log(list)` what do you get? – Kaeros Feb 26 '13 at 18:04
  • Alexander, the html results are the same as above. Nothing is being rendered, not even the tags for the intended results. – richardb Feb 26 '13 at 18:51
  • Your problem looks to be in the browser, not in the Java part. So for conciseness, I'd remove that part and only ask about the javasript/json/html. – flup Mar 16 '13 at 10:54

2 Answers2

4

It seems your serialization is wrong. Since you are generating a sequence of concatenated JSON objects not enclosed properly in an array.

Current invalid JSON response:

{ ... } { ... } { ... } { ... }

Whereas the expected JSON response should be:

[ { ... }, { ... }, { ... }, { ... } ]

No need to do this by hand. Gson may do it automatically for you if you construct the proper object. For example, using something as follows (untested):

List<Map<String, String>> tweetList = new LinkedList<Map<String, String>>();
for (Status tweet : tweets) {
    Map<String, String> tweetResult = new LinkedHashMap<String, String>();
    tweetResult.put("username", tweet.getUser().getScreenName());
    tweetResult.put("status", tweet.getText());
    tweetResult.put("date", tweet.getCreatedAt().toString());
    tweetResult.put("retweets", String.valueOf(tweet.getRetweetCount()));
    tweetList.add(tweetResult);
}
String resultJson = new Gson().toJson(tweetList);
response.getWriter().write(resultJson);

After this fix you should be able to use your original code.


Based on your example JSON output the returned output is an Object, not an Array. You don't need to use $.each here.

$(document).ready(function () {
    $.getJSON('SearchServlet', function(tweet) {
        var table = $('#resultsTable');
        $('<tr>').appendTo(table)
                 .append($('<td>').text(tweet.username))
                 .append($('<td>').text(tweet.status))
                 .append($('<td>').text(tweet.date))
                 .append($('<td>').text(tweet.retweets));
    });
});
Alexander
  • 23,432
  • 11
  • 63
  • 73
  • Hi Alexander, I tried out the code you provided and it's still not rendering the table. Firebug is showing it GETing the data fine, an example being searching for the term "Twitter" resulted in: – richardb Feb 26 '13 at 18:38
  • Firebug console displays the GET response JSON objects, but the dev console on Chrome is showing nothing? Even with console.log(tweet) included in the code? Neither are rendering the table though or even the tags that it should be. – richardb Feb 26 '13 at 18:46
  • @richardb, just to be clear. Is `tweet` being populated? Can you show us the response as Firebug or Chrome Developer Tools is displaying it? – Alexander Feb 26 '13 at 22:38
  • Hi Alexander, I've taken a few screenshots of the console with the results for "Alexander" [first](http://i.imgur.com/kX6EdKt.png), [headers](http://i.imgur.com/hlJoLuq.png) and [full response objects](http://i.imgur.com/yFp9hCO.png) . I also added a console.log("test") after the $.getJSON call but as you can see in the console, it's not logged there and I'm not entirely sure why since it appears the function is, at the very least, calling the doGet on the servlet fine. Thanks for the help, it's much appreciated. – richardb Feb 26 '13 at 22:49
  • Just to follow up on that. I put console.log("test") in [after](http://i.imgur.com/ql0HhaT.png) .ready() is called and it logs to the console fine. If I move it to [within](http://i.imgur.com/bWO4rhh.png) the $.getJSON() is called it doesn't log to the console. If I log "test" to the console [after](http://i.imgur.com/skzBgcY.png) and outside the $.getJSON() it also works fine so it appears there's some issue between the $.getJSON() call and what happens immediately afterward. – richardb Feb 26 '13 at 22:52
  • @richardb, I can see from the third screenshot that the JSON response has an invalid format. You need to add all the `tweetResult` in a list and serialize the list instead. I updated the answer – Alexander Feb 26 '13 at 23:06
  • It works perfectly! Thank you very much Alexander, it's much appreciated. – richardb Feb 27 '13 at 07:39
2

I think the issue is with your use of $.each. Since you are passing in an object, each is iterating over the key-value pairs of the object. (see http://api.jquery.com/jQuery.each/)

You might want to return a JSON object that is wrapped in square brackets, just so it iterates over an array.

[{"username":"Dineen_","status":"RT @TwitterAds: Learn how to put Twitter to work for your small business! Download our small biz guide now: https://t.co/gdnMMYLI","date":"Tue Feb 26 08:37:11 GMT 2013","retweets":"22"}]

EDIT: As Alexander points out, you can just return the same object as you already do, but NOT use the $.each at all. My answer assumes you want to be able to pass back several objects and insert every one in a table row.

Steve
  • 8,609
  • 6
  • 40
  • 54