farling42 / obsidian-import-json

Plug-in for Obsidian.md which will create Notes from JSON files
MIT License
88 stars 5 forks source link

utils.createFrame is not a function #8

Closed AmbushXXVI closed 2 years ago

AmbushXXVI commented 2 years ago

Thanks for the importer, I've finally got time to work through creating a template to import spells from 5etools. I'm attempting to use the forEach helper from handlebars-helpers library. During the import, I get the above error in the console. I've included the relevant block from my template below, as well as the json. Any ideas or suggestions as to what I'm doing wrong?

Uncaught (in promise) TypeError: utils.createFrame is not a function
    at Object.helpers.forEach (eval at <anonymous> (app.js:1), <anonymous>:8078:24)
    at Object.wrapper2 (eval at <anonymous> (app.js:1), <anonymous>:1351:23)
    at Object.eval [as main] (eval at createFunctionContext (eval at <anonymous> (app.js:1)), <anonymous>:37:108)
    at main (eval at <anonymous> (app.js:1), <anonymous>:1534:36)
    at ret (eval at <anonymous> (app.js:1), <anonymous>:1537:16)
    at ret (eval at <anonymous> (app.js:1), <anonymous>:3373:25)
    at JsonImport.eval (eval at <anonymous> (app.js:1), <anonymous>:44334:20)
    at Generator.next (<anonymous>)
    at fulfilled (eval at <anonymous> (app.js:1), <anonymous>:36:24)
{{#forEach entriesHigherLevel}}
## At Higher Levels

{{entriesHigherLevel.0.entries}}
{{/forEach}}
[
    {
        "name": "Intellect Fortress",
        "source": "TCE",
        "page": 107,
        "level": 3,
        "school": "A",
        "time": [
            {
                "number": 1,
                "unit": "action"
            }
        ],
        "range": {
            "type": "point",
            "distance": {
                "type": "feet",
                "amount": 30
            }
        },
        "components": {
            "v": true
        },
        "duration": [
            {
                "type": "timed",
                "duration": {
                    "type": "hour",
                    "amount": 1
                },
                "concentration": true
            }
        ],
        "entries": [
            "For the duration, you or one willing creature you can see within range has resistance to psychic damage, as well as advantage on Intelligence, Wisdom, and Charisma saving throws."
        ],
        "entriesHigherLevel": [
            {
                "type": "entries",
                "name": "At Higher Levels",
                "entries": [
                    "When you cast this spell using a spell slot of 4th level or higher, you can target one additional creature for each slot level above 3rd. The creatures must be within 30 feet of each other when you target them."
                ]
            }
        ],
        "damageResist": [
            "psychic"
        ],
        "damageImmune": [
            "psychic"
        ],
        "damageVulnerable": [
            "psychic"
        ],
        "miscTags": [
            "SGT"
        ],
        "classes": {
            "fromClassList": [
                {
                    "name": "Artificer",
                    "source": "TCE"
                }
            ],
            "fromClassListVariant": [
                {
                    "name": "Bard",
                    "source": "PHB",
                    "definedInSource": "TCE"
                },
                {
                    "name": "Sorcerer",
                    "source": "PHB",
                    "definedInSource": "TCE"
                },
                {
                    "name": "Warlock",
                    "source": "PHB",
                    "definedInSource": "TCE"
                },
                {
                    "name": "Wizard",
                    "source": "PHB",
                    "definedInSource": "TCE"
                }
            ]
        },
        "hasFluffImages": true
    }
]
farling42 commented 2 years ago

Inside the forEach block you should use the keyword 'this' to refer to the current item in the array. So replace the x.0.field with this.field

farling42 commented 2 years ago

Note that in your handlebars you reference "entries" directly, but that is another array, so you will need another forEach block to read each individual entry in that array (even though there is only one, you still need to access it like an array of more than one). Something similar to:

{{#forEach entriesHigherLevel}}
## At Higher Levels
{{#forEach this.entries}}
this
{{/forEach}}
{{/forEach}}
AmbushXXVI commented 2 years ago

Hrm. Thanks for pointing out that I'd missed that inner block. Unfortunately, I can't seem to get a forEach to work anywhere. I also tried with the fromClassListVariant, but I'm still getting the same createFrame error.

Class Variants (forEach): {{#forEach classes.fromClassListVariant}}{{this.name}} {{/forEach}}
AmbushXXVI commented 2 years ago

So, not sure what's going on, but I tried using #each instead of the helper #forEach and it worked. Unfortunately, I don't really know if this will have any other effects down the line...

Update: Ahh. So other helper functions like isLast don't work with each.

AmbushXXVI commented 2 years ago

Any chance you've had time and inclination to look at this? Still trying to figure out if it's my code, my source, or something in the import tool.

Thanks

farling42 commented 2 years ago

I just had a look, and #forEach is broken in my distribution. I am trying to find how to include the required modules to get that working properly.

ckennedy666 commented 2 years ago

It looks like match from Handlebars-Helpers is also missing some modules, perhaps related.

farling42 commented 2 years ago

I've changed the plugin to use a fork of handlebars-helpers (see https://github.com/Budibase/handlebars-helpers) which builds properly. This means that #forEach should now work properly in 0.12.0

AmbushXXVI commented 2 years ago

thanks for taking the time to fix this :)