lcazarre
lcazarre

Reputation: 743

How to simplify my JavaScript function with a for loop?

I wrote the following JavaScript function to retrieve stock information from Yahoo Finance. I would like to streamline the code with a for loop, to avoid repeating these three lines:

var cell = row.insertCell(0);
var newText = document.createTextNode(data.query.results.quote.Symbol);
cell.appendChild(newText);

I tried to replace the above with these lines, to no avail. Would you have any suggestion?

var dataElement=[data.query.results.quote.Symbol,
    data.query.results.quote.StockExchange,
    data.query.results.quote.Ask,
    data.query.results.quote.Bid,
    data.query.results.quote.PERatio,
    data.query.results.quote.DividendYield,
    data.query.results.quote.PriceBook];

for (i = 0; i < dataElement.length; i++) {  
    var cell = row.insertCell(i);
    var newText =document.createTextNode(dataElement[i]);
    cell.appendChild(newText);
}

Here is the complete HTML / js code, without the for loop:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-GB" xml:lang="en-GB">

<head>
    <meta charset="UTF-8" /> 
    <title>
        Retrieve stock data from Yahoo Finance
    </title>
    <script type="text/javascript" src="jQuery.js"></script>
</head>

<body>
    <input type="text" id="inputSymbol" />

    <table id='stockDataTable'>
        <thead>
            <tr>
                <td>Symbol</td>
                <td>Stock Exchange</td>
                <td>Ask</td>
                <td>Bid</td>
                <td>PE Ratio</td>
                <td>Dividend Yield</td>
                <td>Price-to-Book Ratio</td>
            </tr>           
        </thead>
        <tbody>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3" id='status'></td>
            </tr>
        </tfoot>
    </table>

    <button type="submit" onClick="addTicker();">Add Ticker to Table</button>
    <button type="submit" onClick="deleteTicker();">Remove Ticker from Table</button>

    <script type="text/javascript">
        function addTicker() {
            var url = "http://query.yahooapis.com/v1/public/yql";
            var symbol = $("#inputSymbol").val();
            var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");

            var table = document.getElementById("stockDataTable").getElementsByTagName('tbody')[0];
            var row = table.insertRow(table.rows.length);

            $.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
                .done(function (data) {

                    var cell = row.insertCell(0);
                    var newText = document.createTextNode(data.query.results.quote.Symbol);
                    cell.appendChild(newText);

                    var cell = row.insertCell(1);
                    var newText = document.createTextNode(data.query.results.quote.StockExchange);
                    cell.appendChild(newText);

                    var cell = row.insertCell(2);
                    var newText = document.createTextNode(data.query.results.quote.Ask);
                    cell.appendChild(newText);

                    var cell = row.insertCell(3);
                    var newText = document.createTextNode(data.query.results.quote.Bid);
                    cell.appendChild(newText);

                    var cell = row.insertCell(4);
                    var newText = document.createTextNode(data.query.results.quote.PERatio);
                    cell.appendChild(newText);

                    var cell = row.insertCell(5);
                    var newText = document.createTextNode(data.query.results.quote.DividendYield);
                    cell.appendChild(newText);

                    var cell = row.insertCell(6);
                    var newText = document.createTextNode(data.query.results.quote.PriceBook);
                    cell.appendChild(newText);
            })
                .fail(function (jqxhr, textStatus, error) {
                var err = textStatus + ", " + error;
                    $("#status").text('Request failed: ' + err);
            });
        }
    </script>

    <script type="text/javascript">
        function deleteTicker() {
            var symbol = $("#inputSymbol").val();
            try {
            var table = document.getElementById("stockDataTable");
            var rowCount = table.rows.length;

            for(var i=0; i<table.rows.length; i++) {
                if(table.rows[i].cells[0].innerHTML == symbol) {
                    table.deleteRow(i);
                    i--;
                }
            }
            }catch(e) {
                alert(e);
            }
        }
    </script>


</body>
</html>

Upvotes: 1

Views: 192

Answers (2)

lcazarre
lcazarre

Reputation: 743

Here is an improved version of the webpage, thanks to gfrobenius' help. I have also extended the JavaScript code to enable retrieving a list of tickers (separated by commas).

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-GB" xml:lang="en-GB">

<head>
    <meta charset="UTF-8" /> 
    <title>
        Retrieve stock data from Yahoo Finance
    </title>
    <link rel="stylesheet" type="text/css" href="Yahoo_finance.css" />
    <script type="text/javascript" src="jQuery.js"></script>
</head>

<body>
    <input type="text" id="inputSymbols" />

    <table id='stockDataTable'>
        <thead>
            <tr>
            </tr>           
        </thead>
        <tbody>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3" id='status'></td>
            </tr>
        </tfoot>
    </table>

    <button type="submit" onClick="addTickers();">Add List of Tickers to Table</button>

    <script type="text/javascript">
        function addTickers() {
            var stringSymbols = $("#inputSymbols").val();
            var arraySymbols = stringSymbols.split(",");
            for (var i=0; i<arraySymbols.length; i++) {
                addTicker(arraySymbols[i]);
            }
        }
        function addTicker(symbol) {
            var url = "http://query.yahooapis.com/v1/public/yql";
            var data = encodeURIComponent("select * from yahoo.finance.quotes where symbol in ('" + symbol + "')");
            var table = document.getElementById("stockDataTable").getElementsByTagName('tbody')[0];

            $.getJSON(url, 'q=' + data + "&format=json&diagnostics=true&env=http://datatables.org/alltables.env")
                .done(function (data) {
                    //add table header to show symbols, if it does not exist
                    if (table.rows.length == 0) {
                        var tableHasHeader = false;
                        var rowHeader = table.insertRow(0);
                    } else {
                        var tableHasHeader = true;
                    }
                    var rowData = table.insertRow(table.rows.length);

                    //loop object by keys
                    var i = 0;
                    var tempData = data.query.results.quote;
                    for (var key in tempData) {

                        //add symbol to the header, if it was not populated yet
                        if (tableHasHeader == false) {
                            var cellHeader = rowHeader.insertCell(i);
                            var newText = document.createTextNode(key);
                            cellHeader.appendChild(newText);                
                        }

                        //add data
                        var cellData = rowData.insertCell(i);
                        var newText = document.createTextNode(tempData[key]);
                        cellData.appendChild(newText);

                        i = i + 1;
                    }
                    for (var i=0; i<table.rows.length; i++) {
                        if (typeof table.rows[i].cells[0].innerHTML === "undefined") {
                            alert("undefined");
                            table.deleteRow(i);
                        }                       
                    }
            })
            .fail(function (jqxhr, textStatus, error) {
                var err = textStatus + ", " + error;
                $("#status").text('Request failed: ' + err);
            });
            //alert(table.rows.length);
        }

    </script>

</body>
</html>

Upvotes: 0

gfrobenius
gfrobenius

Reputation: 4067

Here you go: http://jsfiddle.net/KBJT4/10/

There are a few ways to skin this cat but this way is looping the keys of your quote structure. Here is some of the code but run the fiddle to see it in action.

/*simulating your data object*/
var data = {
      query: {
        results: {
          quote: {
            Symbol: 'Symbol_Value',
            StockExchange: 'StockExchange_Value',
            Ask: 'Ask_Value',
            Bid: 'Bid_Value',
            PERatio: 'PERatio_Value',
            DividendYield: 'DividendYield_Value',
            PriceBook: 'PriceBook_Value'
          }
        }
      }
    };

var i = 0;
var tempData = data.query.results.quote; /*shorten this up*/

//loop object by keys
for (var key in tempData) {
    i = i+1;

    //the alerts show you it's working
    //just replace the alerts with the commented out code

    //var cell = row.insertCell(i);
    alert('row.insertCell('+i+')');

    alert(key+': '+tempData[key]);

    //var newText = document.createTextNode('+tempData[key]+');
    var newText = tempData[key]; //you will remove this line also, its here just so the final alert will work
    alert('var newText = document.createTextNode('+tempData[key]+');');

    //cell.appendChild(newText);
    alert('cell.appendChild('+newText+');');
}

UPDATE: I added this line to fiddle: alert(key+': '+data[key]);. It'll help you understand it a little better. Plus if you want to show the key and it's value instead of just the value, this is how you'd do it.

UPDATE: @user3006803 And here is a real working example that doesn't use your hardcoded data structure. It really shows EVERYTHING for the APL symbol.

http://jsfiddle.net/Dp8px/14/

(after you click the button notice the scroll bar that appears, there's a lot of data in the result block)

Upvotes: 2

Related Questions