Skip to Content
Advanced GuidesVisualize

Response Visualization

Bruno provides a powerful visualization feature that allows you to display API response data in a more readable and interactive format using the bru.visualize function. This feature supports multiple providers and formats to help you analyze and present your API data effectively.

bru.visualize(type, config)
  1. type: The type of visualization to render (e.g., ‘table’, ‘html’).

  2. config: A configuration object that includes:

    • name: The name of the visualization instance.

    • provider: The rendering library or provider used to display the visualization (e.g., ‘ag-grid’, ‘react-table’).

    • props: Additional properties required by the provider to configure the visualization.

Supported Visualization Types and Providers

Table Visualization (‘table’)

You can render tables using different providers like ag-grid and react-table.

Using ag-grid

Example:

ag-grid

const rowData = [ { name: 'John Doe', age: 28, email: 'john@example.com', city: 'New York' }, { name: 'Jane Smith', age: 32, email: 'jane@example.com', city: 'London' } ]; const columnDefinitions = [ { field: "name", filter: true, floatingFilter: true }, { field: "age", filter: true, floatingFilter: true }, { field: "email", filter: true, floatingFilter: true }, { field: "city", filter: true, floatingFilter: true } ]; bru.visualize('table', { name: 'table1', provider: 'ag-grid', props: { rowData, columnDefinitions } });

This will render a table using the ag-grid provider with filters enabled on all columns.

Using react-table

Example:

react-table

const rowData1 = Array.from({ length: 2500 }) .map((_) => [ { firstName: 'Tanner', lastName: 'Linsley', age: 24, visits: 100 }, { firstName: 'Tandy', lastName: 'Miller', age: 40, visits: 40 }, { firstName: 'Joe', lastName: 'Dirte', age: 45, visits: 20 }, ]).flat(); const columnDefinitions1 = [ { id: "firstName", cell: (info) => info.getValue(), header: "First Name", meta: { filterVariant: "text" }, }, { id: "lastName", cell: (info) => info.getValue(), header: "Last Name", meta: { filterVariant: "text" }, }, { id: "age", cell: (info) => info.getValue(), header: "Age", meta: { filterVariant: "range" }, }, { id: "visits", cell: (info) => info.getValue(), header: "Visits", meta: { filterVariant: "range" }, } ]; bru.visualize('table', { name: 'table2', provider: 'react-table', props: { rowData: rowData1, columnDefinitions: columnDefinitions1 } });

The header property only accepts string values. Use strings like header: "Column Name".

This example renders a large table using the react-table provider, with custom headers and filter variants.

Using API Response Data

One of the most powerful features of bru.visualize is the ability to transform API responses into visual tables. Here are practical examples of working with real API data:

In Bruno, the parsed API response is stored in res.body

// ✅ Correct const data = res.body; // ❌ Incorrect const data = res.data;

Example 1: Simple User List API

For an API that returns a list of users:

// API URL: https://jsonplaceholder.typicode.com/users // First, let's check the response structure console.log('Response:', res); console.log('Response body:', res.body); // Bruno stores the parsed response in res.body const users = res.body; // Verify we have data if (!Array.isArray(users)) { console.error('Expected array but got:', typeof users); return; } console.log('Number of users:', users.length); const columnDefinitions = [ { field: "id", filter: true }, { field: "name", filter: true, floatingFilter: true }, { field: "email", filter: true, floatingFilter: true }, { field: "phone", filter: true }, { field: "website", filter: true } ]; bru.visualize('table', { name: 'usersTable', provider: 'ag-grid', props: { rowData: users, columnDefinitions } });

Example 2: Nested API Response Data

For APIs returning nested objects, you can flatten the data before visualization:

// API URL: https://jsonplaceholder.typicode.com/users // Bruno stores the parsed response in res.body const users = res.body; // Transform nested data into flat structure const flattenedData = users.map(user => ({ id: user.id, name: user.name, email: user.email, city: user.address?.city || 'N/A', company: user.company?.name || 'N/A', phone: user.phone })); const columnDefinitions = [ { field: "id", filter: true }, { field: "name", filter: true, floatingFilter: true }, { field: "email", filter: true, floatingFilter: true }, { field: "city", filter: true, floatingFilter: true }, { field: "company", filter: true, floatingFilter: true }, { field: "phone", filter: true } ]; bru.visualize('table', { name: 'usersWithDetails', provider: 'ag-grid', props: { rowData: flattenedData, columnDefinitions } });

Example 3: Transforming Complex Data

For complex responses that need transformation before visualization:

// API URL: https://jsonplaceholder.typicode.com/posts // Bruno stores the parsed response in res.body const posts = res.body; // Transform and enhance data const tableData = posts.slice(0, 20).map((post, index) => ({ index: index + 1, title: post.title.substring(0, 50) + '...', // Truncate long titles body: post.body.substring(0, 100) + '...', // Truncate body userId: post.userId, postId: post.id, length: post.body.length })); const columnDefinitions = [ { field: "index", filter: false, width: 80 }, { field: "postId", filter: true, width: 100 }, { field: "userId", filter: true, width: 100 }, { field: "title", filter: true, floatingFilter: true, width: 300 }, { field: "body", filter: true, width: 400 }, { field: "length", filter: true, width: 100 } ]; bru.visualize('table', { name: 'postsTable', provider: 'ag-grid', props: { rowData: tableData, columnDefinitions } });

Example 4: Error Handling with API Data

Always include error handling when working with API responses:

try { // Bruno stores the parsed response in res.body // Check if response has data if (!res.body) { console.error('No response body found'); return; } const data = res.body; // Check if data is an array (for direct array responses) // or if it has a data property (for wrapped responses) const rowData = Array.isArray(data) ? data : data.data; if (!Array.isArray(rowData)) { console.error('Invalid response format. Expected array but got:', typeof rowData); console.log('Response structure:', data); return; } // Verify data is not empty if (rowData.length === 0) { console.log('No data to visualize'); return; } console.log(`Visualizing ${rowData.length} records`); const columnDefinitions = [ { field: "id", filter: true }, { field: "name", filter: true, floatingFilter: true }, { field: "email", filter: true, floatingFilter: true } ]; bru.visualize('table', { name: 'safeDataTable', provider: 'ag-grid', props: { rowData: rowData, columnDefinitions } }); } catch (error) { console.error('Visualization error:', error.message); console.error('Stack trace:', error.stack); }

When working with API responses:

  • Always verify the response structure before accessing nested properties
  • Use optional chaining (?.) to safely access nested data
  • Transform data to match your visualization needs
  • Add meaningful column headers using the field property
  • Enable filters for better data exploration

HTML Visualization (‘html’)

You can also render custom HTML content using the html type. This allows for advanced templating and formatting, such as generating a data table or a report.

Using HTML String

Example:

html

const htmlString = ` <html> <head> <style> table { width: 100%; border-collapse: collapse; } th, td { border: 1px solid black; padding: 8px; } th { background-color: #f2f2f2; } </style> </head> <body> <table> <tr><th>Name</th><th>Age</th><th>Email</th><th>City</th></tr> <tr><td>John Doe</td><td>28</td><td>john@example.com</td><td>New York</td></tr> <tr><td>Jane Smith</td><td>32</td><td>jane@example.com</td><td>London</td></tr> </table> </body> </html> `; bru.visualize('html', { name: 'htmlReport', content: htmlString });

This example will render an HTML table with predefined data using the html type.

Using API Response Data with HTML

You can dynamically generate HTML from API responses:

// API URL: https://jsonplaceholder.typicode.com/users // Bruno stores the parsed response in res.body const users = res.body; // Generate table rows from API data const tableRows = users.slice(0, 10).map(user => ` <tr> <td>${user.id}</td> <td>${user.name}</td> <td>${user.email}</td> <td>${user.phone}</td> </tr> `).join(''); const htmlString = ` <html> <head> <style> body { font-family: Arial, sans-serif; padding: 20px; } h1 { color: #333; } table { width: 100%; border-collapse: collapse; margin-top: 20px; } th { background-color: #4CAF50; color: white; padding: 12px; text-align: left; } td { border: 1px solid #ddd; padding: 10px; } tr:hover { background-color: #f5f5f5; } .summary { background-color: #e3f2fd; padding: 15px; border-radius: 5px; margin-bottom: 20px; } </style> </head> <body> <h1>User Report</h1> <div class="summary"> <strong>Total Users:</strong> ${users.length} </div> <table> <thead> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th>Phone</th> </tr> </thead> <tbody> ${tableRows} </tbody> </table> </body> </html> `; bru.visualize('html', { name: 'userReport', content: htmlString });

Custom Dashboard with Statistics

Create rich dashboards with API data:

// Example with custom stats or API response // Bruno stores the parsed response in res.body const apiData = res.body; // Calculate or extract statistics from your API response const stats = { totalRequests: apiData.length || 0, successRate: 98.5, avgResponseTime: 145 }; const htmlString = ` <html> <head> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 20px; background-color: #f8f9fa; } .dashboard { max-width: 1200px; margin: 0 auto; } .header { text-align: center; margin-bottom: 30px; } .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 30px; } .card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .card-title { color: #666; font-size: 14px; margin-bottom: 10px; } .card-value { font-size: 32px; font-weight: bold; color: #333; } .card-trend { color: #4CAF50; font-size: 14px; margin-top: 5px; } </style> </head> <body> <div class="dashboard"> <div class="header"> <h1>API Analytics Dashboard</h1> <p>Last updated: ${new Date().toLocaleString()}</p> </div> <div class="cards"> <div class="card"> <div class="card-title">Total Requests</div> <div class="card-value">${stats.totalRequests || 0}</div> <div class="card-trend">↑ 12% from last week</div> </div> <div class="card"> <div class="card-title">Success Rate</div> <div class="card-value">${stats.successRate || 0}%</div> <div class="card-trend">↑ 3% improvement</div> </div> <div class="card"> <div class="card-title">Avg Response Time</div> <div class="card-value">${stats.avgResponseTime || 0}ms</div> <div class="card-trend">↓ 15ms faster</div> </div> </div> </div> </body> </html> `; bru.visualize('html', { name: 'dashboard', content: htmlString });

Viewing Your Visualization

  1. Add the visualization code to your request’s script section
  2. Execute the request
  3. Your visualization will be displayed in the panel

Visualization Output

Parameters

NameTypeDescription
typestringThe type of visualization to render. Supported values: 'table', 'html'.
configobjectConfiguration object for the visualization. See below for available properties.

Config Properties

PropertyTypeDescription
namestringName of the visualization instance.
providerstringThe provider or rendering engine to use for the visualization. E.g., 'ag-grid', 'react-table'.
propsobjectAdditional properties required by the provider to configure the visualization.
contentstring(For html type only) The HTML content to render.
Last updated on