Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

JSON to TableView

Hi,

I'm parsing some JSON and putting it in a tableview I have. I am doing this through a search bar, where the user can search for a keyword, and the app will search the API. Here is the event listener for when the search button is clicked:

search.addEventListener('return', function(e)
{
    var searchValue = search.value;

    function getCards(searchValue){

        // create table view data object
        var data = [];

        var xhr = Ti.Network.createHTTPClient();
        xhr.timeout = 1000000;    
        xhr.open("GET","http://api.com/q="+searchValue);

        xhr.onload = function()
        {
            var s = JSON.parse(this.responseText);
        };
        // Get the data
        xhr.send();    
    }

    getCards(searchValue);
    alert(searchValue);
    //alert(search.total_results);
    var newdata = [

        {title:s.total_results, hasDetail:true, header:'Featured'}


    ];

    tableview.setData(newdata,{animated:true});

       search.blur();

});

I can't figure out why the function is not working. Am I missing something? Does anyone see a hole in my code? Thanks a ton.

— asked September 23rd 2010 by Connor Zwick
  • json
  • parse
  • tableview
1 Comment
  • What part is "not working"? The xhr call? parsing of the return value? the creation of the tableview from the resulting data? I assume your api is correctly returning data?

    — commented September 23rd 2010 by karlo kilayko

6 Answers

  • You need to pass an array of TableViewRow objects to tableview.setData. You should loop through the JSON after it has been parsed and create a TableViewRow for each record. Then, push each TableViewRow object into an array. You can then pass this array into tableview.setData(). You can use your existing unused data[] array to hold the rows. If, for example, each record in the JSON had a title, you could insert something like this into the xhr.onload function.

    
    for (var c=0;c<s.length;c++) {
        var row = Ti.UI.createTableViewRow({
            height: 30,
            title: s[c].title
        });
    
        data.push(row);
    }
    

    Then, set the table data:

    tableview.setData(data);
    

    Also, you may want to try checking the contents you're receiving from the web service both before and after parsing it. You can just use Titanium.API.info() for this.

    — answered September 23rd 2010 by Doug C
    permalink
    0 Comments
  • +1 for Dougs solution, struggled with this for a couple of days myself.

    — answered September 23rd 2010 by Stephen McElhinney
    permalink
    0 Comments
  • you need to call tableView.setData() from within the onload event handler. Otherwise there is no guarantee (and it is quite likely to not happen) that "s" will be set to the result values at that point of execution.

    — answered September 23rd 2010 by Allen Firstenberg
    permalink
    0 Comments
  • I've been struggling with this for days now and I still cannot get it to work. I implemented Doug's solution (thanks!), but there still lies a problem with my onload function:

    search.addEventListener('return', function(e)
    {
        var searchValue = search.value;
    
        function getCards(searchValue){
    
            // create table view data object
            var data = [];
    
            var xhr = Ti.Network.createHTTPClient();
            xhr.timeout = 1000000;    
            xhr.open("GET","http://api.com/q="+searchValue);
    
            xhr.onload = function()
            {
                alert('hi');        
                var s = JSON.parse(this.responseText);
                for (var c=0;c<s.length;c++) {
                    var row = Ti.UI.createTableViewRow({
                        height: 30,
                        title: s[c].title
                    });
    
                    data.push(row);
                }
    
                Titanium.API.info(this.responseText);
                tableview.setData(data);
    
            };
    
            // Get the data
            xhr.send();    
        }
    
        getCards(searchValue);
        Titanium.API.info('this still works');
    
        //tableview.setData(newdata,{animated:true});
    
           search.blur();
    
    });
    

    The alert('hi') does nothing, even if I remove everything else from the onload function. Does anyone see an issue with this code?

    Thanks a ton.

    — answered September 29th 2010 by Connor Zwick
    permalink
    0 Comments
  • Have you tried adding this to see if there is an error being returned?

      xhr.onerror = function(e) { 
        Ti.API.info(e); 
      };
    
    — answered September 29th 2010 by John McKnight
    permalink
    0 Comments
  • Hm…Thanks for that. I did what you suggested, and it helped:

    error = "Error Domain=ASIHTTPRequestErrorDomain Code=1 \"A connection failure occurred\" UserInfo=0x7e947b0 {NSUnderlyingError=0x7e947e0 \"The operation couldn\U2019t be completed. Connection refused\", NSLocalizedDescription=A connection failure occurred}";
    source = "[object TiNetworkClient]";
    type = error;
    }
    

    Unfortunately I do not know how to fix this. Is anyone familiar with a solution to this? I know I am correctly linking to the API and the API is reliable, because I've tested and used it with other things.

    Thanks

    (Also, I don't know/think this is important but I also get a 'Hex color passed looks invalid:' warning, if that tells you something)

    — answered September 30th 2010 by Connor Zwick
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.