4

I'm trying to pass a JSON array of integers but getJSON is not reading it. (it reads fine when I use a dummy JSON array found here https://jsonplaceholder.typicode.com/users)

Tried adding &callback=? to deal with the CORS based on the suggestion here (Changing getJSON to JSONP) since my api is in another project.

Issues encountered:

  1. callback not working with getJSON (i.e. HTML table shown but still not populated.)

Failed to load resource: the server responded with a status of 404 ()

  1. following error was thrown but I'm not sure if they are related.

jquery.dataTables.min.css.: Uncaught SyntaxError: Unexpected token {

JSON array api

// GET api/dbretrieve
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        //TEST
        HashSet<int> db = new HashSet<int>() { 2, 3, 5, 7, 11, 13 };

        string json_string = "";
        json_string = json_string + '[';
        foreach (int s in db)
        {
            json_string = json_string + "{pid:" + s + "},";
        }
        if(Data.db.Count>0) json_string = json_string.Substring(0, json_string.Length - 1);
        json_string = json_string + ']';
        var json = JsonConvert.DeserializeObject(json_string);
        return StatusCode(200, json);
    }

getJSON

<script>
$(document).ready(function () {
    $.getJSON("https://localhost:44399/api/dbretrieve&callback=?", function (data) {
        var employee_data = '';
        $.each(data, function (key, value) {
            employee_data += '<tr>';
            employee_data += '<td>' + '</td>';
            employee_data += '<td>' + value.pid + '</td>';
            employee_data += '</tr>';
        });
        $('#employee_table tbody').append(employee_data);
});
});
</script>

JSON array being passed

[{"pid":2},{"pid":3},{"pid":5},{"pid":7},{"pid":11},{"pid":13}]

HTML

<body>
<div class="container">
    <div class="table-responsive">
        <h1>Testing of database table</h1>
        <br />
        <table class="table table-bordered table-striped" 
        id="employee_table">
            <thead>
                <tr>
                    <th>#</th>
                    <th>pid</th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>

    </div>
</div>
<form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
</form>
</body>

Headers for HTML

<head runat="server">
<title>JSON data to HTML</title>
<script src="Scripts/jquery-3.0.0.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/d3js/5.9.0/d3.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
 <script src="Scripts/bootstrap.min.js"></script>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css"></script>

<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
user3803747
  • 292
  • 2
  • 5
  • 14
  • I just copy+pasted your jQuery and your array [with no issues](https://jsfiddle.net/cveo94hb/). Can you share the HTML? **EDIT:** Your `$.getJSON` is missing a closing tag, but you said there were no errors, so I have to assume that's just a typo in the question. – Tyler Roper Jun 04 '19 at 02:52
  • @TylerRoper Hi, yup it was a typo. Thanks for the heads up :) I've edited my post along with the HTML – user3803747 Jun 04 '19 at 03:02
  • Your array - did you `console.log(data)` to get that? Are you absolutely certain that's what `data` represents in the JavaScript? – Tyler Roper Jun 04 '19 at 03:14
  • @TylerRoper yes the data is being passed through just fine and it (the url) works with Postman. However i'm being thrown an "No 'Access-Control-Allow-Origin' header is present on the requested resource" error in the console log – user3803747 Jun 04 '19 at 03:27
  • There is some issue in your API call. It might be not giving you proper result as you want. – Dilip Oganiya Jun 04 '19 at 06:42
  • @Dilip thanks for the reply. The strange thing is if I remove "&callback=?" from my url in $.getJSON (i.e. "https://localhost:44399/api/dbretrieve") I will be able to see my JSON array but my table will not be populated due to CORS not allowing me to access the api in multiple projects – user3803747 Jun 04 '19 at 06:49
  • In your Ajax call, add below property and let me know : headers: { 'Access-Control-Allow-Origin': 'htt://site allowed to access' }, – Dilip Oganiya Jun 04 '19 at 06:54
  • Please check and let me know – Dilip Oganiya Jun 04 '19 at 06:56

2 Answers2

4

You need to add the CORS header at your server side, there are many ways to do this, see this answer.

I will go with the most obvious way of decorating the EnableCors attribute on top of your action method.

For now it will allow every origin, header and method to access your action method for testing purpose, but in production change it to only selected origin, headers and methods.

Now, you can go ahead and re-factor your code to this instead of doing string concatenation:

// GET api/dbretrieve
[HttpGet]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public JsonResult Get()
{
    HashSet<int> db = new HashSet<int>() { 2, 3, 5, 7, 11, 13 };

    // Project into your desired list
    var pidList = db.Select(x => new
    {
        pid = x
    });

    return Json(pidList, JsonRequestBehavior.AllowGet);
}

Refactor your HTML code to this:

<!DOCTYPE html>

<head>
  <title>JSON data to HTML</title>
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

  <!-- jQuery library -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

  <!-- Popper JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>

  <!-- Latest compiled JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

  <!-- Latest D3.js -->
  <script src="https://d3js.org/d3.v5.min.js"></script>

  <!-- Latest jQuery Datatable CDN -->
  <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <script src="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css"></script>

  <script>
    $(document).ready(function() {

      function getData(callback) {
        const serverUrl = "http://localhost:44399/api/dbretrieve";
        $.ajax({
          url: serverUrl,
          type: 'GET',
          dataType: 'json',
          contentType: "application/json;charset=utf-8",
          success: function(data) {
            callback(data);
          },
          error: function(jqXHR, textStatus, errorThrown) {
            console.log(textStatus);
          }
        });
      }

      function populateTable(data) {
        const table = $('#employee_table');
        table.find("tbody tr").remove();
        data.forEach(x => {
          table.append("<tr><td> </td><td>" + x.pid + "</td></tr>");
        });
      }

      // Get data from server now
      getData(populateTable);
    });
  </script>
</head>

<body>
  <div class="container">
    <div class="table table-hover table-responsive">
      <h1>Testing of database table</h1>
      <br />
      <table class="table table-bordered table-striped" id="employee_table">
        <thead>
          <tr>
            <th>#</th>
            <th>pid</th>
          </tr>
        </thead>
        <tbody>
        </tbody>
      </table>

    </div>
  </div>
</body>
Kunal Mukherjee
  • 5,775
  • 3
  • 25
  • 53
-3

try adding 'min-width: 700px;' to table.

Remya
  • 55
  • 4