I am trying to use Pug to generate a datalist based on data from another .js file. My problem is figuring out how to get Pug to read this javascript object
I currently have a wizardSpells.js file withe the following data:
// wizardSpells.js
const wiz1 = {};
wiz1['Affect Normal Fires'] = {'school': 'Alteration'};
wiz1['Alarm'] = {'school': 'Abjuration, Evocation'};
wiz1['Armor'] = {'school': 'Conjuration'};
Here is the content of my datalist.pug file:
//datalist.pug
datalist(id='wiz1-spells')
each val, key in wiz1
option(value=val.school) key
The error I get when I try to compile the pug file into HTML is the following:
TypeError: .\pug\datalists.pug:2
1| datalist(id='wiz1-spells')
> 2| each val, key in wiz1
3| option(value=val.school) key
Cannot read property 'length' of undefined
My problem clearly is that my javascript object is undefined in the datalist.pug file.
How do I get Pug to access my javascript file and the javascript object? I would highly prefer a solution that does not edit the wizardSpells.js file, and keep all changes within the datalists.pug file.
Additional info
- Pug has been installed via Node with
npm install pug-cli
- I generate my html via the pug-cli with the following command:
pug .\pug\datalists.pug -o ./html -P
I have all the files locally available on my machine so no network or big setup is necessary. All I need Pug to do, is to read the local file and use it for generating output.
CodePudding user response:
You have to export the object from wizardSpells.js
to be able to access it.
// wizardSpells.js
const wiz1 = {};
wiz1['Affect Normal Fires'] = {'school': 'Alteration'};
wiz1['Alarm'] = {'school': 'Abjuration, Evocation'};
wiz1['Armor'] = {'school': 'Conjuration'};
module.exports = { wiz1 };
Alternatively, don't use the pug-cli
package, use the pug
package instead and generate the HTML output from NodeJS directly.
// build.js
const pug = require('pug');
const wizardSpells = require('./wizardSpells.js');
const html = pug.renderFile('datalist.pug', wizardSpells);
console.log(html);
CodePudding user response:
Using the answer above I managed to make it work. My final setup looks like this:
// wizardSpells.js
const wiz1 = {};
wiz1['Affect Normal Fires'] = {'school': 'Alteration'};
wiz1['Alarm'] = {'school': 'Abjuration, Evocation'};
wiz1['Armor'] = {'school': 'Conjuration'};
module.exports = wiz1;
The javascript wiz1
object is exported directly without any wrapper object.
// build.js
const pug = require('pug');
const fs = require('fs');
const wiz1= require('./wizardSpells.js');
const html = pug.renderFile('../src/datalist.pug', {pretty: true, wiz1: wiz1});
fs.writeFileSync('datalist.html', html);
I send the wiz1
object to pug in the pug.renderFile()
line, but it seems that pug is unable to serve the "root object" for iteration, and only the properties of the root object can be accessed. Therefore I wrap the wiz1
object in another object, and also add the pretty: true
flag to get nicely indented HTML.
This now allows me to access the wiz1
object in my pug file:
// datalist.pug
datalist(id='wiz1-spells')
each val, key in wiz1
option(value=val.school)= key
To run everything I use the following command: node build.js
The final HTML looks like this:
<datalist id="wiz1-spells">
<option value="Alteration">Affect Normal Fires</option>
<option value="Abjuration, Evocation">Alarm</option>
<option value="Conjuration">Armor</option>
</datalist>
Note: As I also use the wizardSpells.js
as content for my final HTML, I have a post processing step that removes the module.export
line, before insertion, to avoid it breaking the javascript when it is added to the HTML and loaded by the browser.