Why doesn’t my DataTable load dynamically when the page first loads (works only after refresh)?

First poster here.

I’m using DataTables with server side processing and an AJAX call to load the table’s data based on a selected dimension. However, when the page first loads the table is not populated with data until I manually refresh.

I’ve checked the AJAX request, and it seems to work fine after the refresh, but it doesn’t trigger on the first page load.

Here’s what I’m doing:

  1. I initialize the table and set it to load data via AJAX.
  2. I’m using a dropdown (#dimensionDropdown) to select a dimension.
  3. The table data should load based on the selected dimension (defaulting to the top selection in the dropdown)

What I’ve Tried:

  1. The table loads fine after refreshing the page, but not initially.
  2. I’ve checked the network tab, and the AJAX request is made after the refresh.

Can anyone help me understand why the table is not loading on the first session and how I can fix this?

Here’s my Python route:

@app.route('/project/PROJECT_ID/tab/control/table/data', methods=['GET'])
def product_control_table_json(project_id):
    print(f"Incoming AJAX request for JSON table — project_id: {project_id}")

    projects = load_projects()
    project = next((p for p in projects if p["id"] == "PROJECT_ID"), None)
    if not project:
        return jsonify({"data": []})

    all_reports = load_all_reports()
    product_reports = [r for r in all_reports if r['id'].startswith("PROJECT_ID") and r.get("report_type") == "product"]

    if not product_reports:
        return jsonify({"data": []})

    latest_report = sorted(product_reports, key=lambda r: r["timestamp"], reverse=True)[0]
    df = pd.DataFrame(latest_report["data"], columns=latest_report["columns"])
    df = clean_dataframe(df)

    if "Category Level 1" in df.columns and "Category Level 2" in df.columns:
        df["Category_CONCAT"] = df["Category Level 1"] + " " + df["Category Level 2"]

    selected_dimension = request.args.get("dimension", "Brand")

    if selected_dimension not in df.columns:
        return jsonify({"data": []})

    search_value = request.args.get('search[value]', '')
    if search_value:
        df = df[df[selected_dimension].str.contains(search_value, case=False, na=False)]

    grouped = df.groupby(selected_dimension, as_index=False).agg({
        "Product ID": "count",
        "Conversions": "sum"
    })

    order_column = int(request.args.get('order[0][column]', 0))
    order_dir = request.args.get('order[0][dir]', 'asc')
    grouped = grouped.sort_values(by=grouped.columns[order_column], ascending=(order_dir == 'asc'))

    rows = []
    for _, row in grouped.iterrows():
        val = row[selected_dimension]
        rows.append({
            "dimension": val,
            "count": row["Product ID"],
            "conversions": row["Conversions"],
            "checkbox_1": f'<input type="checkbox" name="specific_asset_group_values" value="{val}">',
            "checkbox_2": f'<input type="checkbox" name="force_tier1_values" value="{val}">'
        })

    return jsonify({
        "draw": request.args.get('draw', type=int, default=1),
        "recordsTotal": len(df),
        "recordsFiltered": len(grouped), 
        "data": rows
    });

And here’s my Javascript:

$(document).ready(function() {
  var table = $('#productTable').DataTable({
    processing: true,
    serverSide: true,
    paging: false,  
    ajax: {
      url: '/project/PROJECT_ID/tab/control/table/data',  
      data: function(d) {
        d.dimension = $('#dimensionDropdown').val();
      },
      cache: false,
      dataSrc: function(json) {
        $('#rowCount').text(json.data.length);
        return json.data;
      }
    },
    columns: [
      { data: 'dimension' },
      { data: 'count' },
      { data: 'conversions' },
      { data: 'checkbox_1' },
      { data: 'checkbox_2' }
    ]
  });

  $('#dimensionDropdown').val('Brand'); 
  table.ajax.reload(); 

  $('#dimensionDropdown').on('change', function() {
    table.ajax.reload(); 
  });
});