With Kanka 2.4, a partial JavaScript dump was added for entity attributes and a handful of other information. As of 2.7, this object now includes most of the entity’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):
console.log(entityData)
{
"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 entities:
"gender": "...",
"pronouns": "...",
"title": "...",
"age": "...",
"traits": [ ... ], // and appearances
"races": [ ... ],
"families": [ ... ],
"location": { ... }
}
Note that the attribute 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 attributes whose name is invalid in Blade, for example those that contain special characters, as long as you know their corresponding slug.
Axios API
Kanka 2.7 introduced tools to access the API via axios methods that interact with an entity’s attributes and abilities. This allows us to generate a far more thorough attribute dump (including for example attribute types and 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 attribute/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 attribute 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 attributes for which you know the exact form of both slugs (forget running a forEarch in one using attributes passed by the other!).
All of that said, here is some boilerplate that will fetch attributes 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.
function dumpAttributes (resp, dump = {}) {
// Sanitize attribute 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 attributes from the API
axios.get(attributeApis.all.url).then(res => {
window.attributes = dumpAttributes(res.data.data);
console.log(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.log(abilities); // optional, useful for debugging
/* Call any functions that require the dump here */
}).catch(err => {
console.error("Failed to create ability dump");
});
};
Each attribute value can then be accessed with a simple attributes.slug.value, where slug matches the attribute’s corresponding Blade variable:
window.alert("Welcome to " + attributes.CharacterName.value + "’s character sheet!");
Remember: entityData attributes are all lower-case and can be accessed directly. API attributes are case-sensitive and have several properties, so you need to specify .value to get the value. entityData.attributes.charactername = attributes.CharacterName.value.
Several other details are available via attributes.slug, beyond what is accessible in Blade; for example: