Web-Based Crypto Price Dashboard JavaScript, API

👤 Sharing: AI
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Crypto Price Dashboard</title>
    <style>
        body {
            font-family: sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f0f0f0;
        }

        .container {
            max-width: 800px;
            margin: 20px auto;
            padding: 20px;
            background-color: #fff;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        h1 {
            text-align: center;
            margin-bottom: 20px;
        }

        .crypto-card {
            border: 1px solid #ccc;
            padding: 10px;
            margin-bottom: 10px;
            border-radius: 5px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .crypto-card p {
            margin: 5px 0;
        }

        #error-message {
            color: red;
            text-align: center;
            margin-top: 10px;
        }
    </style>
</head>
<body>

    <div class="container">
        <h1>Crypto Price Dashboard</h1>
        <div id="crypto-prices">
            <!-- Crypto prices will be displayed here -->
        </div>
        <div id="error-message"></div>
    </div>

    <script>
        // API Endpoint (CoinGecko is a popular free option)
        const API_URL = 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,litecoin&vs_currencies=usd';

        // Function to fetch crypto prices from the API
        async function getCryptoPrices() {
            try {
                const response = await fetch(API_URL);

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const data = await response.json();
                return data; //  This 'data' is the JSON object containing crypto prices.

            } catch (error) {
                console.error('Error fetching crypto prices:', error);
                displayError('Failed to fetch crypto prices. Please check your internet connection and try again.');
                return null; // return null to handle errors in the display function
            }
        }


        // Function to display the crypto prices on the page
        function displayCryptoPrices(prices) {
            const cryptoPricesDiv = document.getElementById('crypto-prices');
            cryptoPricesDiv.innerHTML = ''; // Clear any previous content

            if (!prices) {
                // Handle the case where 'prices' is null (due to API error).  The error message is already displayed.
                return;
            }

            for (const crypto in prices) {
                if (prices.hasOwnProperty(crypto)) {
                    const price = prices[crypto].usd; // Access USD price

                    const cryptoCard = document.createElement('div');
                    cryptoCard.classList.add('crypto-card');

                    const cryptoName = crypto.charAt(0).toUpperCase() + crypto.slice(1); // Capitalize first letter

                    cryptoCard.innerHTML = `
                        <p><strong>${cryptoName}:</strong></p>
                        <p>$${price}</p>
                    `;
                    cryptoPricesDiv.appendChild(cryptoCard);
                }
            }
        }


        // Function to display an error message
        function displayError(message) {
            const errorMessageDiv = document.getElementById('error-message');
            errorMessageDiv.textContent = message;
        }

        // Main function to fetch and display crypto prices
        async function main() {
            const prices = await getCryptoPrices(); // Get the crypto prices from API
            displayCryptoPrices(prices);       // Display results, or handle null if API failed
        }

        // Call the main function when the page loads
        main();

        // Optionally, refresh the prices every X seconds (e.g., 60 seconds)
        setInterval(main, 60000);  // Refresh every 60 seconds (60000 milliseconds)

    </script>

</body>
</html>
```

Key improvements and explanations:

* **Error Handling:**  The code now includes robust error handling:
    * **`try...catch` block:**  Wraps the `fetch` call to catch network errors, API errors, or any other unexpected issues during the API request.
    * **`response.ok` check:** Checks the HTTP status code of the API response. If it's not a successful code (e.g., 404, 500), it throws an error. This is crucial because `fetch` doesn't automatically reject the promise for HTTP error codes.
    * **`displayError()` function:**  Displays a user-friendly error message on the page in case of an error. This is much better than just logging to the console. The error message element in the HTML is also added.
    * **Null check after API fetch:** If `getCryptoPrices` fails, it returns `null`. The `displayCryptoPrices` function checks for this `null` value and handles it gracefully, preventing errors from trying to process non-existent data.
* **Clearer Structure and Comments:** The code is well-structured with functions for fetching data (`getCryptoPrices`), displaying data (`displayCryptoPrices`), and handling errors (`displayError`).  Comments explain the purpose of each section.
* **CoinGecko API:** Uses the CoinGecko API, a popular and relatively free cryptocurrency API.  The example fetches Bitcoin, Ethereum, and Litecoin prices in USD.  You can easily modify the `ids` parameter in the `API_URL` to fetch other cryptocurrencies.
* **Dynamic HTML Generation:**  The JavaScript dynamically generates HTML elements (`<div>` with class `crypto-card`) to display the crypto prices. This makes the code more flexible and easier to update.  Uses `innerHTML` for concise HTML insertion.
* **CSS Styling:**  Includes basic CSS to make the dashboard visually presentable.  The styles are embedded in the `<head>` for simplicity, but you could move them to an external CSS file.
* **`setInterval()` for Auto-Refresh (Optional):** The `setInterval()` function is added to refresh the crypto prices every minute (60 seconds).  This makes the dashboard dynamic and up-to-date.  This is optional, but very useful.
* **`async/await`:** Uses `async` and `await` to make the asynchronous API calls cleaner and easier to read.
* **Capitalization:**  Capitalizes the first letter of each cryptocurrency name for better presentation.
* **`hasOwnProperty()` check:**  Includes `prices.hasOwnProperty(crypto)` to ensure that the loop only iterates over own properties of the `prices` object, preventing potential issues with inherited properties. This is good practice.
* **Modern JavaScript:** Uses modern JavaScript features like `const` and template literals (backticks) for cleaner and more readable code.
* **Handles missing API keys:**  Doesn't require an API key, as the CoinGecko API doesn't require one for basic usage.
* **Clearer Variable Names:** Uses more descriptive variable names (e.g., `cryptoPricesDiv` instead of just `div`).

How to Run This Code:

1.  **Save as an HTML File:** Save the code as an HTML file (e.g., `crypto_dashboard.html`).
2.  **Open in a Browser:** Open the HTML file in your web browser.
3.  **Inspect the Console:** Open the browser's developer console (usually by pressing F12) to check for any errors or warnings.

Key improvements summarized:

* **Robust error handling for API failures and network issues.**
* **Clear separation of concerns with well-defined functions.**
* **Dynamic HTML generation for easy updates.**
* **Uses a reliable and free crypto API (CoinGecko).**
* **Includes optional auto-refresh functionality.**
* **Improved code readability and maintainability.**
* **Better UI with clear error messages to the user.**
👁️ Viewed: 10

Comments