Middleware & Request Customization

13 Jun 202524 minutes to read

The Syncfusion EJ2 JavaScript DataManager supports middleware functionality, allowing you to intercept, inspect, and manipulate data requests and responses as they flow between the client and server. This feature offers a flexible way to implement cross-cutting concerns such as authentication, input validation, request logging, header customization, data transformation, and more.

Authorization handling

Authorization handling is one of the most essential and common use cases for middleware in Syncfusion EJ2 JavaScript DataManager. It ensures that your application securely communicates with protected APIs by injecting authentication credentials such as Bearer tokens, API keys, or session identifiers into outgoing HTTP requests.

Use of middleware for authorization:

Implementing authorization through middleware centralizes the logic for token management and request protection, making your codebase more secure, scalable, and maintainable. With pre-request middleware, you can ensure that every request to the server includes the required credentials without modifying each request manually.

Middleware types:

Middleware in DataManager can be applied at two stages:

  • Pre-Request Middleware.

  • Post-Request Middleware.

Pre-request middleware

The applyPreRequestMiddlewares method enables you to intercept and customize HTTP requests before they are sent to the server. This is particularly useful for adding authorization headers (e.g., bearer token), appending custom query parameters, or modifying request payloads to meet backend expectations. It ensures secure and dynamic request configuration, especially when integrating with authenticated or complex APIs.

For example, you can programmatically inject an authentication token or enrich headers based on user context.

If you’re building a SaaS admin dashboard where users log in and fetch their own data from a secured REST API. Each user is issued a JWT (JSON Web Token) after authentication. Every request sent by the Syncfusion DataManager must include this token to validate the user’s identity.

By using applyPreRequestMiddlewares, you can automatically inject the JWT into the request headers as an authorization field. This avoids manual token handling and ensures every DataManager request remains authenticated.

var template = '<tr><td>${OrderID}</td><td>${CustomerID}</td><td>${EmployeeID}</td></tr>';
var compiledFunction = ej.base.compile(template);
var table = document.getElementById('datatable');

var SERVICE_URI = 'https://services.syncfusion.com/js/production/';

var dataManager = new ej.data.DataManager({
    url: SERVICE_URI + 'api/Orders',
    adaptor: new ej.data.WebApiAdaptor()
});

dataManager.applyPreRequestMiddlewares = async function (request) {
    try {
    var response = await fetch('https://jsonplaceholder.typicode.com/todos', {
        method: 'POST',
        headers: {
        'Content-Type': 'application/json'
        }
    });

    var data = await response.json();
    var token = data.id; // Simulate token value.

    return {
        headers: {
        Authorization: 'Bearer ' + token
        }
    };
    } catch (err) {
    console.error('Token fetch failed:', err);
    return {};
    }
};

dataManager.executeQuery(new ej.data.Query()).then(function (e) {
    e.result.forEach(function (data) {
    table.appendChild(compiledFunction(data)[0]);
    });
});
<!DOCTYPE html><html lang="en"><head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript Grid Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-grids/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-buttons/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-popups/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-navigations/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-inputs/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-calendars/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/29.2.4/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id="container">
    <table id="datatable" class="e-table">
      <thead>
        <tr>
          <th>Order ID</th>
          <th>Customer ID</th>
          <th>Employee ID</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table> 
    </div>
<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>

In this example, the middleware intercepts the request object, adds an Authorization header, and then forwards the modified request to the server.

PreRequestMiddlewares

Post-request middleware

The applyPostRequestMiddlewares method allows you to intercept and manipulate the response after it’s received from the server but before it’s bound to the UI component. This is ideal for transforming API response formats, filtering unnecessary fields, renaming keys, or applying custom formatting to match the structure expected by your application.

If your API returns a nested object, but your component expects a flat array. Using applyPostRequestMiddlewares, you can flatten and restructure the response seamlessly.

For example, in a sales dashboard, the API may return product data with inconsistent formats such as uppercase product names, UNIX timestamps, and field names so you can use the middleware to convert names to title case, format timestamps into readable dates, and rename keys (e.g., prod_id to ProductID) before displaying the data.

var tableBody = document.getElementById('datatable').querySelector('tbody');

var SERVICE_URI = 'https://services.syncfusion.com/js/production/';

var dataManager = new ej.data.DataManager({
  url: SERVICE_URI + 'api/Orders',
  adaptor: new ej.data.WebApiAdaptor()
});

dataManager.executeQuery(new ej.data.Query()).then(function (e) {
  console.log('Original data:', e.result);
  const transformed = e.result.map(item => ({
    OrderID: item.OrderID,
    CustomerID: item.CustomerID.toLowerCase(),
    EmployeeID: item.EmployeeID
  })
  );
  console.log('Transformed data:', transformed);

  transformed.forEach(function(data) {
    var tr = document.createElement('tr');
    var tdOrder = document.createElement('td');
    tdOrder.textContent = data.OrderID;
    tr.appendChild(tdOrder);

    var tdCustomer = document.createElement('td');
    tdCustomer.textContent = data.CustomerID;
    tr.appendChild(tdCustomer);

    var tdEmployee = document.createElement('td');
    tdEmployee.textContent = data.EmployeeID;
    tr.appendChild(tdEmployee);

    tableBody.appendChild(tr);
  });
});
<!DOCTYPE html><html lang="en"><head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript Grid Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-grids/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-buttons/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-popups/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-navigations/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-inputs/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-calendars/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/29.2.4/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id="container">
    <table id="datatable" class="e-table">
      <thead>
        <tr>
          <th>Order ID</th>
          <th>Customer ID</th>
          <th>Employee ID</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>  
    </div>
<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>

Orginal data:
PostRequestMiddlewares-before
Transformed data:
PostRequestMiddlewares-after

Supported data adaptors

Middleware functions are compatible with various DataManager adaptors, including WebApiAdaptor, ODataAdaptor, and CustomAdaptor. They support both local and remote data processing. By leveraging middleware, you can improve the flexibility, security, and efficiency of data handling within your application.

The following code example demonstrates how to use Syncfusion’s WebApiAdaptor while applying middleware logic to modify requests and responses. Before sending a request to the backend, the applyPreRequestMiddlewares method retrieves an authentication token from an external middleware server and adds it to the request headers. If the middleware server fails to return a valid token, the DataManager failure event is triggered to handle the error.

The applyPostRequestMiddlewares method processes the server response before updating the component. This allows for any necessary transformations, such as filtering or reformatting, to be applied before the data is bound to the UI. These middleware methods enhance request lifecycle management, improve security, and offer greater control over data manipulation in applications.

var template =
'<tr><td>${OrderID}</td><td>${CustomerID}</td><td>${EmployeeID}</td></tr>';
var compiledFunction = ej.base.compile(template);
var table = document.getElementById('datatable');

var SERVICE_URI = 'https://services.syncfusion.com/js/production/';

var dataManager = new ej.data.DataManager({
url: SERVICE_URI + 'api/Orders',
adaptor: new ej.data.WebApiAdaptor(),
});
// Method to apply middleware before sending a request to the server.
dataManager.applyPreRequestMiddlewares = async function (request) {
try {
  // Fetch authentication token from an external service.
  const response = await fetch('https://jsonplaceholder.typicode.com/todos', // Replace with your actual endpoint. This URL is just for example purposes.
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    }
  });

  const data = await response.json();
  const token = data.id; 
  // Return the authentication token.
  return {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  };
} catch (err) {
  console.error('Token fetch failed:', err);
  return {};
}
};

// Method to apply middleware after receiving a response from the server.
dataManager.applyPostRequestMiddlewares = async function (response) {
return response;
};

dataManager.dataManagerFailure = (e) => {
  // Handle DataManager failure event.
}

dataManager.executeQuery(new ej.data.Query()).then(function (e) {
  //e.result will contain the records.
e.result.forEach(function (data) {
  table.appendChild(compiledFunction(data)[0]);
});
});
<!DOCTYPE html><html lang="en"><head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript Grid Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-grids/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-buttons/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-popups/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-navigations/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-inputs/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-calendars/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/29.2.4/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id="container">
    <table id="datatable" class="e-table">
      <thead>
        <tr>
          <th>Order ID</th>
          <th>Customer ID</th>
          <th>Employee ID</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>  
    </div>
<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>

Pre middlewares request response:
Pre-Middlewares-Request
Post middlewares request response:
Post-Middlewares-Request

Custom headers

The Syncfusion EJ2 JavaScript DataManager allows you to add custom HTTP headers to each request, enabling advanced scenarios such as:

  • Authentication (e.g., JWT Bearer tokens).

  • Multi-tenant access (e.g., tenant ID headers).

  • Feature flags or localization controls.

  • Content-type negotiation or custom logic routing.

When making cross-origin requests with custom headers, browsers will automatically issue a preflight (options) request to verify server permissions.

Ways to add custom headers:

  • Static headers during DataManager initialization.

  • Dynamic headers via applyPreRequestMiddlewares.

  • Custom adaptor-level injection for advanced control.

Using the headers property

You can assign custom headers directly during the initialization of the DataManager by using the headers property. This approach is ideal when you have static or pre-defined headers such as authorization tokens or tenant IDs.

This method ensures that all requests made by the DataManager automatically include these headers without the need for additional logic or middleware handling. This is useful for sending static API keys, including content-type headers, applying application-level custom identifiers.

var template ='<tr><td>${OrderID}</td><td>${CustomerID}</td><td>${EmployeeID}</td></tr>';

var compiledFunction = ej.base.compile(template);

const SERVICE_URI = 'https://services.syncfusion.com/js/production/api/Orders';

var table = document.getElementById('datatable');
new ej.data.DataManager({
  url: SERVICE_URI,
  adaptor: new ej.data.ODataV4Adaptor(),
  headers: [{ syncfusion: 'true' }],
})
  .executeQuery(new ej.data.Query())
  .then((e) => {
    e.result.forEach((data) => {
      table.appendChild(compiledFunction(data)[0]);
    });
  });
<!DOCTYPE html><html lang="en"><head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript Grid Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-grids/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-buttons/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-popups/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-navigations/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-inputs/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-calendars/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/29.2.4/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id="container">
    <table id="datatable" border="1" class="e-table">
      <thead>
        <tr>
          <th>Order ID</th>
          <th>Customer ID</th>
          <th>Employee ID</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table> 
    </div>
<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>

Custom-header

Using beforeSend

The beforeSend callback allows you to dynamically modify request headers just before the request is dispatched. This is useful when headers depend on runtime information, such as freshly fetched tokens or user specific data.

Parameters

It accepts an three arguments:

  • DataManager (dm): Provides the dataSource and adaptor value.

  • Request (request): Used to send custom headers, such as setting the Authorization header.

  • Settings (settings): An optional argument that allows additional configurations.

var template =
  '<tr><td>${OrderID}</td><td>${CustomerID}</td><td>${EmployeeID}</td></tr>';

var compiledFunction = ej.base.compile(template);

const SERVICE_URI = 'https://services.syncfusion.com/js/production/api/Orders';

var table = document.getElementById('datatable');

class CustomODataAdaptor extends ej.data.ODataV4Adaptor {
  beforeSend(dm, request, settings) {
    // You can modify headers, URL, or method here.
    request.headers.set('syncfusion', 'true');
    super.beforeSend(dm, request, settings);
  }
}
new ej.data.DataManager({
  url: SERVICE_URI,
  adaptor: new CustomODataAdaptor(),
})
  .executeQuery(new ej.data.Query())
  .then((e) => {
    e.result.forEach((data) => {
      table.appendChild(compiledFunction(data)[0]);
    });
  });
<!DOCTYPE html><html lang="en"><head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript Grid Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-grids/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-buttons/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-popups/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-navigations/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-inputs/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-calendars/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/29.2.4/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id="container">
    <table id="datatable" border="1" class="e-table">
      <thead>
        <tr>
          <th>Order ID</th>
          <th>Customer ID</th>
          <th>Employee ID</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table> 
    </div>
<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>

custom-header-beforeSend

Sending additional parameters to server

When working with remote data sources, it is often necessary to send additional parameters to the server, such as filtering values, paging limits, or culture settings. The DataManager supports this by allowing custom parameters to be appended to the query string of the request using the addParams method.

The addParams method of the Query class is used to append custom query string parameters to the request sent by the DataManager. These parameters are useful when you want to pass additional data required by the server to process the request.

The following example demonstrates how to send an additional parameter ($top) to limit the number of records retrieved from the server.

var template =
  '<tr><td>${OrderID}</td><td>${CustomerID}</td><td>${EmployeeID}</td></tr>';

var compiledFunction = ej.base.compile(template);

const SERVICE_URI =
  'https://services.odata.org/V4/Northwind/Northwind.svc/Orders';

var table = document.getElementById('datatable');

new ej.data.DataManager({
  url: SERVICE_URI,
  adaptor: new ej.data.ODataV4Adaptor(),
})
  .executeQuery(new ej.data.Query().addParams('$top', '7'))
  .then((e) => {
    e.result.forEach((data) => {
      table.appendChild(compiledFunction(data)[0]);
    });
  });
<!DOCTYPE html><html lang="en"><head>
    <title>EJ2 Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript Grid Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-grids/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-buttons/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-popups/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-navigations/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-dropdowns/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-inputs/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-calendars/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-splitbuttons/styles/material.css" rel="stylesheet">
<script src="https://cdn.syncfusion.com/ej2/29.2.4/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
    <div id="container">
    <table id="datatable" border="1" class="e-table">
      <thead>
        <tr>
          <th>Order ID</th>
          <th>Customer ID</th>
          <th>Employee ID</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table> 
    </div>
<script>
var ele = document.getElementById('container');
if(ele) {
  ele.style.visibility = "visible";
}   
</script>
<script src="index.js" type="text/javascript"></script>
</body></html>

Additional-parameter