ejs icon indicating copy to clipboard operation
ejs copied to clipboard

Helper function render [Object object]

Open PatrykMaternicki opened this issue 7 years ago • 1 comments

Normally, when I use include is correct, but when I Use my helpers function then write me [Object object]

So, this is a helpers. <%- helpers.js_assets_load('RegisterValid', data.props) %> First argument is which file load. Next argument is a props to set to constructor. Controler:

class RegisterSiteControler extends BaseControler {
  constructor(req, app, response) {
    super(req, app);
    this.data = {
      countUser: response.countUser,
      props: {
        data: [
          { 'port': ApiConfig.port },
          { 'log_route_email' : 'log/email/'},
          {'log_route_nick' : '/log/nick/'},
        ],
        parentNode: 'formRegister',
      },
    }
    this.init();
  }

  init() {
    super.mergeData(this.data);
  }
}

module.exports = RegisterSiteControler;

This is a EJSExtension:

const EJSExtension = {
  config: '',
  engine: {},
  fs: {},

  setConfig: function(config) {
    this.config = config;
    this.engine= require('ejs');
    this.fs = require('fs');
  },

  assets: function(file) {
    const basePath = this.config.assetsSetings.basic_url;
    const cssUrl = this.config.assetsSetings.css_assets_url;
    const url = `${basePath}${cssUrl}${file}.css`;
    const assetsUrl = '/../views/helpers/assets/css.ejs';
    const compiled = this.engine.compile(this.fs.readFileSync(__dirname + assetsUrl, 'utf8'));
    return compiled({ url: url });
  },

  js_assets_load: function(file, props = {}, moduleName = '') {
    const jsUrl = props.js_assets_url ? props.js_assets_url : this.config.assetsSetings.js_assets_url;
    const assetsUrl = '/../views/helpers/assets/require-js.ejs';
    const compiled = this.engine.compile(this.fs.readFileSync(__dirname + assetsUrl, 'utf8'));
    props.moduleName = moduleName === '' ? file : moduleName;
    props.args = [];
    props.filename = file;
    props.js_assets_url = jsUrl;
    props.args = props.data;
    return compiled({ props : props });
  }
}

module.exports = EJSExtension;

Template:

<script>
  require.config({
    context: '<%= props.filename %>',
    baseUrl: "<%= props.js_assets_url %>",
    waitSeconds: 60
    })(['<%= props.filename %>'], function(Lib) {
      new Lib.<%= props.moduleName %>({
        'parentNode' : document.getElementById('<%= props.parentNode %>'),
        'data': {
          <% for(var i=0; i < props.args.length; i++) {%>
            <% var key = Object.keys(props.args[i])[0] %>
            <% var value = Object.values(props.args[i])[0] %>
            "<%= key %>" : "<%= value %>",
          <% } %>
        }
      });
    });
</script>

Is working, but EJS script put a big whitespaces and code is looking ugly. Of course I use a whitespace flag in express. So Do you have better idea to resolve this problem?

PatrykMaternicki avatar Dec 16 '18 18:12 PatrykMaternicki

You didn't put whitespace-stripping tags in the scriptlet tags. You need to use some whitespace-stripping tags for your scriptlets. Relevant section, edited:

        'data': {
          <%_ for(var i=0; i < props.args.length; i++) { _%>
            <% var key = Object.keys(props.args[i])[0] _%>
            <% var value = Object.values(props.args[i])[0] %>
          "<%= key %>" : "<%= value %>",
          <%_ } %>
        }

This will indent the items correctly, with a newline before each item. The curly brace is in the correct place.

It should create output like this (untested):

        'data': {
          "key" : "value",
          "key" : "value",
          "key" : "value",
          "key" : "value",
        }

LoganDark avatar Mar 11 '19 16:03 LoganDark