Search code examples
javascriptandroidtitaniumcloudtitanium-mobile

Titanium: Display Custom Object - variable undefined


I'm a newbie to Titanium and web development. I'm trying to retrieve the custom object that I created and stored on ACS. I spent hours on it and got stuck because I don't know how I can retrieve a set of data fields correctly from the Cloud. My code compiles, but the table view does not show up. I only see the title and back button. I believe the error is inside the "Cloud.Objects.Query" block (It should display 4 entries, each with a date, place, and review), but I don't see any of them. I tried using alerts and one of the alert messages I keep getting is "the variable is undefined". Can someone take a look and give me some hints? Thank you for your time.

    //Import the module
var Cloud = require('ti.cloud');
Cloud.debug = true;  // optional; if you add this line, set it to false for production 

// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');

exports.getDiaryWin = function() {

    //create window
    var diary_window = Titanium.UI.createWindow({
        backgroundColor:'#FFF',
        title: "Travel Diary"
    });

    //create title
    var title = Titanium.UI.createLabel({
        text: "My Travel Diary",
        top:10,
        color: '#008000',
        textAlign: 'center',
        font: {fontSize:55}
    });

    var tableView = Ti.UI.createTableView({
        top: '10%',
        scrollable: true,
        width: '100%',
        minRowHeight: '50',
        bottom: '10%'
    });

    //Get diary entries, add them to the table view and display it  
    var idList = [];
    var tableData = [];
    var displayData = [];
    var entry;

    //Get diary id 
    Cloud.Objects.query({
        classname: 'diaries',
        page: 1,
        per_page: 10
    },function(e){
        if (e.success){
            alert('Count: '+e.diaries.length);

        for (var i=0; i<e.diaries.length; i++)
            {
                entry = e.diaries[i];
                /*
                alert('id: ' + entry.id + '\n' +
                'date: ' + entry.date + '\n' +
                'place: ' + entry.place + '\n' +
                'review: ' + entry.review + '\n' +
                'created_at: ' + entry.created_at);
                */
                tableData.push({
                    date: entry.date,
                    place: entry.place,
                    review: entry.review
                });

                alert('tableData:' + tableData.date);   //ALERT: tableData: UNDEFINED

            }   
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }   
    });


    /*
    tableData.push({
        date: 'Can u see this?'
    });
    */

    for (var i=0; i < tableData.length; i++){
        var row = Ti.UI.createTableViewRow({
            height:150,
            backgroundColor : '#FF9900',
            font: {fontSize:35},
            title: tableData[i].date
        });

        /*
        var dateField = Ti.UI.createLabel({
            text:tableData[i].date,
            font: {fontSize:35}, 
            color:'#888', 
            left:5, 
            width:Ti.UI.FILL
        });
        row.add(dateLabel);

        var placeLabel = Ti.UI.createLabel({
            text:tableData[i].place,
            font: {fontSize:35}, 
            color:'#888', left:5, width:Ti.UI.FILL
        });
        row.add(placeLabel);

        var reviewLabel = Ti.UI.createLabel({
            text:tableData[i].review,
            font: {fontSize:35}, 
            color:'#888', 
            left:5, 
            width:Ti.UI.FILL
        });
        row.add(reviewLabel);
        */
        displayData.push(row);
    }

    tableView.setData(displayData);

    //add a 'back' button
    var back_button = Titanium.UI.createButton({
        title: "Back",  
        buttom:20,
        height:200,
        left:40,
        right:40    
    });     

    //Add Event Listener
    back_button.addEventListener('click', function(){
        //call an export function
        var win = require('home').getHomeWin;

        //create new instance
        var nextWin = new win();
        nextWin.open();
    });


    diary_window.add(title);
    diary_window.add(tableView);
    diary_window.add(back_button);
    return diary_window;

};

------------EDITED CODE --------------

//Import the module
var Cloud = require('ti.cloud');
Cloud.debug = true;  // optional; if you add this line, set it to false for production 

// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');

exports.getDiaryWin = function() {

    //create window
    var diary_window = Titanium.UI.createWindow({
        backgroundColor:'#FFF',
        title: "Travel Diary"
    });

    //create title
    var title = Titanium.UI.createLabel({
        text: "My Travel Diary",
        top:10,
        color: '#008000',
        textAlign: 'center',
        font: {fontSize:55}
    });

    var tableView = Ti.UI.createTableView({
        top: '10%',
        scrollable: true,
        width: '100%',
        minRowHeight: '50',
        bottom: '10%'
    });

    //Get diary entries, add them to the table view and display it  
    var idList = [];
    var tableData = [];
    var displayData = [];
    var entry;

    //Get diary id 
    Cloud.Objects.query({
       classname: 'diaries',
       page: 1,
       per_page: 10
    }, function(e) {
        var row, dateLabel, placeLabel, reviewLabel;
        var displayData = [];

        if (e.success){    
            alert('Count: '+e.diaries.length);

            for (var i=0; i<e.diaries.length; i++) {
                entry = e.diaries[i];
                row = Ti.UI.createTableViewRow({
                    height:150,
                    backgroundColor : '#FF9900',
                    font: {fontSize:35},
                    title: entry.date
                });

                dateLabel = Ti.UI.createLabel({
                    text: entry.date,
                    font: {fontSize:35}, 
                    color:'#888', 
                    left:5, 
                    width:Ti.UI.FILL
                });
                row.add(dateLabel);

                placeLabel = Ti.UI.createLabel({
                    text: entry.place,
                    font: {fontSize:35}, 
                    color:'#888', left:5, width:Ti.UI.FILL
                });
                row.add(placeLabel);

                reviewLabel = Ti.UI.createLabel({
                    text: entry.review,
                    font: {fontSize:35}, 
                    color:'#888', 
                    left:5, 
                    width:Ti.UI.FILL
                });
                row.add(reviewLabel);

                displayData.push(row);
            }

            tableView.setData(displayData);
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }   
    });

    //add a 'back' button
    var back_button = Titanium.UI.createButton({
        title: "Back",  
        buttom:20,
        height:200,
        left:40,
        right:40    
    });     

    //Add Event Listener
    back_button.addEventListener('click', function(){
        //call an export function
        var win = require('home').getHomeWin;

        //create new instance
        var nextWin = new win();
        nextWin.open();
    });


    diary_window.add(title);
    diary_window.add(tableView);
    diary_window.add(back_button);
    return diary_window;

};

Solution

  • Error "the variable is undefined" is triggered on alert('tableData:' + tableData.date); because you are trying to access date property on whole array not one of the objects stored in array. Change it to, for example:

    alert('tableData:' + tableData[0].date);
    

    You should also move whole for loop inside callback. You have to wait for response from Cloud API to start populating your TableView:

    Cloud.Objects.query({
           classname: 'diaries',
           page: 1,
           per_page: 10
    }, function(e) {
        var row, dateField, placeLabel, reviewLabel;
        var displayData = [];
    
        if (e.success){    
            alert('Count: '+e.diaries.length);
    
            for (var i=0; i<e.diaries.length; i++) {
                entry = e.diaries[i];
                row = Ti.UI.createTableViewRow({
                    height:150,
                    backgroundColor : '#FF9900',
                    font: {fontSize:35},
                    title: entry.date
                });
    
                dateField = Ti.UI.createLabel({
                    text: entry.date,
                    font: {fontSize:35}, 
                    color:'#888', 
                    left:5, 
                    width:Ti.UI.FILL
                });
                row.add(dateLabel);
    
                placeLabel = Ti.UI.createLabel({
                    text: entry.place,
                    font: {fontSize:35}, 
                    color:'#888', left:5, width:Ti.UI.FILL
                });
                row.add(placeLabel);
    
                reviewLabel = Ti.UI.createLabel({
                    text: entry.review,
                    font: {fontSize:35}, 
                    color:'#888', 
                    left:5, 
                    width:Ti.UI.FILL
                });
                row.add(reviewLabel);
    
                displayData.push(row);
            }
    
            tableView.setData(displayData);
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }   
    });