# Exposing properties and other entry information

### entityData

With Kanka 2.4, a partial JavaScript dump was added for properties and a handful of other information. As of 2.7, this object now includes most of the entry’s information relevant to a character sheet, with the notable exception of abilities. You can access it via the `entityData` object, which contains the following fields (further detailed on the [official Helper page](https://marketplace.kanka.io/helpers/template-html#javascript)):

{% code title="console.log(entityData)" overflow="wrap" %}

```javascript
{
  "name": "...",
  "is_private": true|false,
  "type": { ... },
  "attributes": { ... },
  "tags": [ ... ],
  "type_field": "...",
  "is_dead": true|false, // Characters and Creatures only
  "is_extinct": true|false, // Races and Creatures only
  "is_completed": true|false, // Quests only
  "is_defunct": true|false, // Organizations only
  "is_destroyed": true|false, // Locations only
  // The rest are only included for Character entries:
  "gender": "...",
  "pronouns": "...",
  "title": "...",
  "age": "...",
  "traits": [ ... ], // and appearances
  "races": [ ... ],
  "families": [ ... ],
  "location": { ... }
}
```

{% endcode %}

{% hint style="warning" %}
Note that the property names used by `entityData` are "sluggified" and don’t match their Blade counterparts when it comes to capitalization, which can make interactions between the two languages difficult. On the other hand, it makes it possible to interact with properties whose name is invalid in Blade, for example those that contain special characters, as long as you know their corresponding slug.
{% endhint %}

### Axios API

Kanka 2.7 introduced tools to access the API via `axios` methods that interact with an entry’s properties **and** abilities. This allows us to generate a far more thorough property dump (including, for instance, property types and their pinned status) with names that match those used in Blade, as well as a detailed dump of ability information.

However, because axios is only initialized after the page is fully loaded, unlike our character sheet scripts, `window.onload` is necessary to defer execution until axios is ready. Any processing that relies on the property/ability dumps must therefore also be deferred. Since you have to wait until the page finishes loading to make the API request, *then* wait for the data to be returned by the API, this introduces a significant delay to your data processing. If you try building an empty layout in Blade and filling it with content using axios-provided data in JavaScript, you will see that it can take more than a second before your layout gets populated, resulting in a poor user experience.

Therefore, it is advisable to do any time-sensitive initial processing and content-building with `entityData` or Blade – though again, since property names differ between `entityData` and the API, you have to be vigilant about your references, and cross-references between the two are more or less impossible unless you are targeting specific properties for which you know the exact form of both slugs (forget running a `forEach` in one using properties passed by the other!).

All of that said, here is some boilerplate that will fetch properties and abilities from the API, format the former to match Blade variable names, and either run any API-dependent code or log an error if something goes wrong.

{% code overflow="wrap" lineNumbers="true" %}

```javascript
function dumpAttributes (resp, dump = {}) {
  // Sanitize property names for PHP, removing [range] if applicable, to match Blade variables
  resp.forEach(obj => {
    dump[obj.name.replace(/\[range:.*\]|[^a-zA-Z0-9_\x80-\xff]/g, "")] = obj;
  });
  return dump;
}

window.onload = (event) => {
  // Collect properties from the API
  axios.get(attributeApis.all.url).then(res => {
    window.attributes = dumpAttributes(res.data.data);
    console.table(attributes); // optional, useful for debugging

    /* Call any functions that require the dump here */
  }).catch(err => {
    console.error("Failed to create attribute dump");
  });
  
  // Collect abilities from the API
  axios.get(abilityApis.all.url).then(res => {
    window.abilities = res.data.data;
    console.table(abilities); // optional, useful for debugging

    /* Call any functions that require the dump here */
  }).catch(err => {
    console.error("Failed to create ability dump");
  });
};
```

{% endcode %}

Each property value can then be accessed with a simple `attributes.slug.value`, where `slug` matches the property’s corresponding Blade variable:

{% code overflow="wrap" %}

```javascript
window.alert("Welcome to " + attributes.CharacterName.value + "’s character sheet!");
```

{% endcode %}

{% hint style="warning" %}
Remember: `entityData` properties are all lower-case and can be accessed directly. API properties are case-sensitive and have several properties, so you need to specify `.value` to get the value. `entityData.attributes.charactername` = `attributes.CharacterName.value`.
{% endhint %}

Several other details are available via `attributes.slug`, beyond what is accessible in Blade; for example:

{% code overflow="wrap" %}

```json
{
  "id": 6640309,
  "name": "Multiclass Domain[range:Arcana,Blade,Bone,Codex,Grace,Midnight,Sage,Splendor,Valor]", // unparsed string
  "name_raw": "Multiclass Domain[range:Arcana,Blade,Bone,Codex,Grace,Midnight,Sage,Splendor,Valor]", // unparsed string (no difference as far as I can tell)
  "value": '3 <i class="ra ra-aura" aria-hidden="true"> <iframe src="https://app.kanka.io/w/1/entities/1/attributes-dashboard" data-entity-tags="id-1 dicemacro" data-entity-type="note" class="entity-attributes-render w-full h-full"></iframe>', // parsed entry/property mentions and icons (e.g. [icon:ra ra-aura]) - ** EMPTY = "" **
  "value_raw": "{Number} [icon:ra ra-aura] [note:1|field:attributes]", // unparsed string - ** EMPTY = null **
  "type_id": 1,
  "is_section": false,
  "is_number": false,
  "is_multiline": false,
  "is_checkbox": false,
  "is_random": false,
  "is_private": false,
  "is_pinned": true,
  "is_hidden": false,
  "apis": {
    "update": {
      "method": "POST",
      "url": "https://app.kanka.io/w/1/entities/2/attributes/live-api/6640309"
    },
    "delete": {
      "method": "POST",
      "url": "https://app.kanka.io/w/1/entities/2/attributes/live-api/6640309/delete"
    }
  }
}
```

{% endcode %}

Most notably, the `apis` object provides the necessary URLs to [implement our own live-editing](https://salvatos.gitbook.io/kanka-cookbook/plugin-creators/javascript-in-character-sheets/live-editing-properties-via-the-api) for properties.

We also get a ton of information about abilities, grouped by their parent field like in the Abilities page of the entry; for example:

{% code overflow="wrap" %}

```json
{
  "groups": [
    {
      "id": 0,
      "name": "Unorganised",
      "type": "Abilities are grouped by their parent field, and fallback to being here.",
      "abilities": [
        {
          "id": 174521,
          "ability_id": 17663,
          "name": "Hypercognition",
          "entry": "<p>HYPERCOGNITION</p><p><b>Level:</b> 6 Divination<br><b>Casting Time:</b> 1 half action<br><b>Distance:</b> Personal<br><b>Duration:</b> 1 hour per Casting Level<br><b>Effect:</b> You gain a +6 magic bonus with Search and Sense Motive checks. As a half action, you may end this spell early to gain a +12 magic bonus with a single Investigate check.<br></p>",
          "type": "Spell",
          "charges": null,
          "used_charges": null,
          "class": [
            " kanka-tag-73914",
            " kanka-tag-wip"
          ],
          "note": "",
          "tags": [
            {
              "id": 73914,
              "name": "WIP",
              "url": "https://app.kanka.io/w/1/entities/2"
            }
          ],
          "visibility_id": 1,
          "visibility": "Unknown",
          "created_by": 22039,
          "attributes": [
            {
              "id": 1175745,
              "name": "Level",
              "value": "6 Divination",
              "type": ""
            },
            {
              "id": 1175746,
              "name": "Casting Time",
              "value": "1 half action",
              "type": ""
            }
          ],
          "images": {
            "has": false,
            "thumb": "",
            "url": ""
          }
        }
      ]
    }
  ],
  "meta": {
    "add_url": "https://app.kanka.io/w/1/entities/2/entity_abilities/create",
    "user_id": 10101,
    "is_admin": true
  }
}
```

{% endcode %}

[![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyMi77TBIT8fo4eUKGoVg%2Fuploads%2F6ELDa9DsgmOPCikdriMn%2Frest-cdd7684ae7838a2edd4a643c9403151f-suapruoq.jpg?alt=media\&token=beaafbda-04de-4e7e-ba7c-35cba52a0990)](https://ko-fi.com/salvatos)
