1

I have this JSON response code from my script:

{
  "id": 159690,
  "name": "Product name",
  "categories": {
    "2068": "Category one",
    "1760": "Category two",
    // ...
  }
}

I want to append checkboxes to #chkrole the with value and name from the JSON response. Instead, my code is giving me the following error.

Uncaught SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

Why is this happening? Here is my code:

$.ajax({
  url: '<?php echo base_url(); ?>admin/grab_product_next',
  data: form.serialize(),
  type: 'post',
  dataType: 'JSON',
  success: function(resp) {
    $('input#name').val(name);

    var json = JSON.parse(resp.categories);
    var val = 0;
    var table = $('<table></table>');
    var option = json.map(x =>
      table.append($('<tr></tr>').append($('<td></td>').append($('<input>').attr({
        type: 'checkbox',
        name: 'chkRoles',
        value: x.chkName,
        id: 'chkrole' + val
      }))).append(
        $('<label>').attr({
          for: 'chkRoles' + val++
        }).text(x.chkName))));

    $('#chkrole').append(table);
  }
})
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Catalin
  • 23
  • 2
  • The error message tells you that your "JSON" is not "JSON". – freedomn-m Sep 09 '22 at 08:00
  • Change `var json = JSON.parse(resp.categories);` -> `var json = resp.categories;` (and probably give it a better name) – freedomn-m Sep 09 '22 at 08:00
  • Remember: [JSON is always a string](https://stackoverflow.com/questions/383692/what-is-json-and-what-is-it-used-for) – freedomn-m Sep 09 '22 at 08:02
  • and you have `#chkrole` within the table DOM element that you are trying to create further you are appending the table to `#chkrole` which is super unclear. And moreover, you have unique `chkrole` ids created by incrementing val. What are you trying to do in this particular line `$('#chkrole').append(table);`? – kavigun Sep 09 '22 at 08:15

1 Answers1

0

The issue is because you don't need to use JSON.parse - jQuery has already done that for you.

You can also simplify and improve the code by using a template to hold the HTML instead of creating some convoluted JS logic to build it. This is a better approach as it follows the Separation of concerns principle.

You should also avoid putting id attributes in dynamic HTML. You can instead wrap the input within the label and remove both the id and for attributes, like this:

// mock AJAX response:
let resp = {
  "id": 159690,
  "name": "Product name",
  "categories": {
    "2068": "Category one",
    "1760": "Category two"
  }
}

// outside $.ajax success handler:
let rowTemplate = $('#table-row-template').html().trim();

// inside $.ajax success handler:
var rows = Object.entries(resp.categories).map(c => rowTemplate.replace(/{{id}}/gi, c[0]).replace(/{{name}}/gi, c[1]));
$('<table />').append(rows).appendTo('#chkRole');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="chkRole"></div>

<template id="table-row-template">
  <tr>
    <td>
      <label>
        <input type="checkbox" name="chkRoles" value="{{id}}" />
        {{name}}
      </label>
    </td>
  </tr>
</template>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339