Home > Blockchain >  Access javascript object outside pug file
Access javascript object outside pug file

Time:11-01

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.

  • Related