Is there a method to upload files directly to a Domo Brick?

I’m working with bricks and trying to upload files directly to a brick on my dashboard to use in my ETL. I want to understand the correct process for uploading files and if there are any specific configurations or APIs involved.

Currently, when I drag a file into my brick, the 'file-name' section in the HTML updates to reflect the uploaded file’s name. However, none of the backend parsing done by the JavaScript is working as expected. The file seems to upload correctly to the front end, but the processing script or actions that should be triggered on the back end don’t seem to be firing. To me Im assuming that the HTML is picking. up the file but there is no change registered in the DOM.

If anyone has a better understanding or has completed a Brick like this one, please let me know what steps you used to debug this process.

Additionally, is there a better way to test and develop Domo Bricks that makes it easier to debug issues like this one? Any tools, techniques, or best practices that could help streamline the development process and improve debugging would be greatly appreciated.

Thank's in advance for your help!

Tagged:

Best Answer

  • ArborRose
    ArborRose Coach
    Answer ✓

    Generally, when I create a Domo brick I use notepad ++ and create an html file to work through the problem. If it works in html, I then try putting into the Domo brick and work from there.

    In this case, I can make a solution work in native html and JavaScript, but it isn't working in Domo. Paste the following into an html text file such as test.html.

    <html>
    <head>
    <style>
    </style>
    </head>
    <script>
    document.addEventListener("DOMContentLoaded", function () {
    const fileInput = document.getElementById("file-input");
    const uploadButton = document.getElementById("upload-button");
    const fileNameDisplay = document.getElementById("file-name");
    const statusMessage = document.getElementById("status-message");
    const parsedOutput = document.getElementById("parsed-output");

    let uploadedFile = null;

    // Update file name when a file is selected
    fileInput.addEventListener("change", (event) => {
    if (event.target.files.length > 0) {
    uploadedFile = event.target.files[0];
    fileNameDisplay.textContent = `Selected File: ${uploadedFile.name}`;
    } else {
    fileNameDisplay.textContent = "No file selected";
    uploadedFile = null;
    }
    });

    // Handle the upload process
    uploadButton.addEventListener("click", async () => {
    if (!uploadedFile) {
    updateStatus("Please select a file before uploading.", "red");
    return;
    }

    try {
    // Read file content
    const fileContent = await readFileContent(uploadedFile);

    // Parse CSV content
    const parsedData = parseCSV(fileContent);

    // Display parsed data in the UI
    parsedOutput.textContent = JSON.stringify(parsedData, null, 2);

    updateStatus("File uploaded and processed successfully!", "green");
    } catch (error) {
    updateStatus(`Error: ${error.message}`, "red");
    }
    });

    // Utility: Read file content
    function readFileContent(file) {
    return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = () => reject(reader.error);
    reader.readAsText(file);
    });
    }

    // Utility: Parse CSV content
    function parseCSV(content) {
    const rows = content.trim().split("\n");
    const headers = rows[0].split(",");

    return rows.slice(1).map((row) => {
    const values = row.split(",");
    return headers.reduce((obj, header, index) => {
    obj[header.trim()] = values[index]?.trim();
    return obj;
    }, {});
    });
    }

    // Utility: Update status message
    function updateStatus(message, color) {
    statusMessage.textContent = message;
    statusMessage.style.color = color;
    }
    });

    </script>
    <body>
    <div id="file-upload-brick">
    <input type="file" id="file-input" />
    <button id="upload-button">Upload</button>
    <p id="file-name">No file selected</p>
    <p id="status-message"></p>
    <pre id="parsed-output" style="background-color: #f0f0f0; padding: 10px; border: 1px solid #ccc;"></pre>
    </div>

    </body>
    </html>

    Here's a sample csv file:

    Name,Age,Email,City
    Alice,30,alice@example.com,New York
    Bob,25,bob@example.com,Los Angeles
    Charlie,35,charlie@example.com,Chicago
    Diana,28,diana@example.com,Miami

    The resulting output looks like this (below). But doesn't work in the Domo brick. Which doesn't solve your problem but might give you something to work from.

    ** Was this post helpful? Click Agree or Like below. **
    ** Did this solve your problem? Accept it as a solution! **

Answers

  • ArborRose
    ArborRose Coach
    Answer ✓

    Generally, when I create a Domo brick I use notepad ++ and create an html file to work through the problem. If it works in html, I then try putting into the Domo brick and work from there.

    In this case, I can make a solution work in native html and JavaScript, but it isn't working in Domo. Paste the following into an html text file such as test.html.

    <html>
    <head>
    <style>
    </style>
    </head>
    <script>
    document.addEventListener("DOMContentLoaded", function () {
    const fileInput = document.getElementById("file-input");
    const uploadButton = document.getElementById("upload-button");
    const fileNameDisplay = document.getElementById("file-name");
    const statusMessage = document.getElementById("status-message");
    const parsedOutput = document.getElementById("parsed-output");

    let uploadedFile = null;

    // Update file name when a file is selected
    fileInput.addEventListener("change", (event) => {
    if (event.target.files.length > 0) {
    uploadedFile = event.target.files[0];
    fileNameDisplay.textContent = `Selected File: ${uploadedFile.name}`;
    } else {
    fileNameDisplay.textContent = "No file selected";
    uploadedFile = null;
    }
    });

    // Handle the upload process
    uploadButton.addEventListener("click", async () => {
    if (!uploadedFile) {
    updateStatus("Please select a file before uploading.", "red");
    return;
    }

    try {
    // Read file content
    const fileContent = await readFileContent(uploadedFile);

    // Parse CSV content
    const parsedData = parseCSV(fileContent);

    // Display parsed data in the UI
    parsedOutput.textContent = JSON.stringify(parsedData, null, 2);

    updateStatus("File uploaded and processed successfully!", "green");
    } catch (error) {
    updateStatus(`Error: ${error.message}`, "red");
    }
    });

    // Utility: Read file content
    function readFileContent(file) {
    return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = () => reject(reader.error);
    reader.readAsText(file);
    });
    }

    // Utility: Parse CSV content
    function parseCSV(content) {
    const rows = content.trim().split("\n");
    const headers = rows[0].split(",");

    return rows.slice(1).map((row) => {
    const values = row.split(",");
    return headers.reduce((obj, header, index) => {
    obj[header.trim()] = values[index]?.trim();
    return obj;
    }, {});
    });
    }

    // Utility: Update status message
    function updateStatus(message, color) {
    statusMessage.textContent = message;
    statusMessage.style.color = color;
    }
    });

    </script>
    <body>
    <div id="file-upload-brick">
    <input type="file" id="file-input" />
    <button id="upload-button">Upload</button>
    <p id="file-name">No file selected</p>
    <p id="status-message"></p>
    <pre id="parsed-output" style="background-color: #f0f0f0; padding: 10px; border: 1px solid #ccc;"></pre>
    </div>

    </body>
    </html>

    Here's a sample csv file:

    Name,Age,Email,City
    Alice,30,alice@example.com,New York
    Bob,25,bob@example.com,Los Angeles
    Charlie,35,charlie@example.com,Chicago
    Diana,28,diana@example.com,Miami

    The resulting output looks like this (below). But doesn't work in the Domo brick. Which doesn't solve your problem but might give you something to work from.

    ** Was this post helpful? Click Agree or Like below. **
    ** Did this solve your problem? Accept it as a solution! **

  • If your objective is to read a Domo dataset into a brick, but not on-the-fly upload via a button, then this example should help. This example pulls the default dataset, "Example Sales Data". You can pull other datasets into the brick.

    var domo = window.domo;
    var datasets = window.datasets;

    // get the data
    domo.get(`data/v1/${datasets[0]}`).then(function(result){

    // extract desired values (change keys according to your dataset)
    var firstRow = result[0];
    var revenue = firstRow['Revenue'];
    var sales_rep = firstRow['Sales Rep'];
    var department = firstRow['Department'];

    // link to html
    document.getElementById("result").innerHTML = "Revenue: " + revenue + "<br>" +
    "Sales Rep: " + sales_rep + "<br>" +
    "Department: " + department;
    });
    <!DOCTYPE html>
    <html lang="en">

    <body>
    <header>
    <h1>Test</h1>
    </header>
    <p>
    The following example shows how we can get data from a Domo dataset.
    We go to the APPSTORE and load Blank Brick. This sets up a card. The card will
    default with three preloaded datasets. The first one is called
    Example Sales Data. We will use this.</p>
    <p>
    We use javascript to link to the dataset. And pull the result into our variable, result[0].
    Then we can talk to the data and show results like this....
    </p>

    <main>
    <h3>Example data from the dataset</h3>
    <div id="result"></div>
    </main>

    </body>
    </html>

    ** Was this post helpful? Click Agree or Like below. **
    ** Did this solve your problem? Accept it as a solution! **