The best way to pass children like in React



  • What helpers/strategies are recommended by jsreport to pass children like in React?
    So, it could be used like so

    {{#templateWithChildren "wrapper"}}
    <div>I'm going to be passed as children</div>
    {{/templateWithChildren}}

    (here "wrapper" is template name that's gonna receive children prop)

    I tried the following, but it doesn't seem to pass context:

    Handlebars.registerHelper("templateWithChildren", function (name, opts) {
    const children = opts.fn(this);
    return component.call({...this, children}, name, opts)
    })



  • It should work like this
    https://playground.jsreport.net/w/anon/FsJ7qKhw

    function myWrappedComponent(name, opts) {
        const r = opts.fn()  
        return component.call({
            ...opts.data,
            value: r
        }, name, opts)
    }
    

    Note, you typically never need to call Handlebars.registerHelper. Every global function in the helpers part is treated as a helper and jsreport does the same registration for you.



  • Thank you. Is it possible to have it working with components passed as children like so

    {{#templateWithChildren "wrapper"}}
       {{component "first-component"}}
       {{component "second-component"}}
       {{component "third-component"}}
    {{/templateWithChildren}}
    

    And ideally to have components properly rendered inside of "wrapper" like so

    <!-- wrapper.hbs -->
    <body>
      <div id="root">
          {{component "wrapper-header"}}
         {{{children}}}
          {{component "wrapper-footer"}}
      </div>
    </body>
    

    I.e. in the end it should render:

    <body>
      <div id="root">
          {{component "wrapper-header"}}
    
          {{component "first-component"}}
          {{component "second-component"}}
          {{component "third-component"}}
    
          {{component "wrapper-footer"}}
      </div>
    </body>
    


  • The handlebars templating engine isn't react, but it should be robust enough to reach the desired outputs.

    Here is the demo how it could work with handlebars:
    https://playground.jsreport.net/w/anon/1YLRwFWo



  • Awesome. Thank you
    One more question, if possible:
    I implemented everything according to your example. Though I used childTemplate helper instead of component because it didn't seem to work properly with component

    async function componentWithChildren(name, opts) {
      const children = await jsreport.templatingEngines.waitForAsyncHelper(opts.fn())
      return childTemplate.call({
        ...opts.data,
        children
      }, name, opts)
    }
    

    However, I face a problem when some templates and components aren't rendered and there is just "undefined" text instead of them. Do you have any ideas why it might be happening? These components/templates were successfully rendering before I used componentWithChildren helper and some of their neighbors are rendered properly.
    Frankly, I'm not sure how exactly it works under then hood, but I tried:

    • rendering components with no logic at all instead of broken ones and didn't succeed
    • swapping working and broken components and surprisingly working ones remained working whereas broken remained broken. It probably means that there is something with the setup of those components. Though I have no clue what exactly
    • tried the same approach with different template and faced the same problem. Basically 2 child templates were properly rendered whereas others were "undefined"


  • Please share a playground demo replicating the issues.





  • Thank you! It looks like our internal bug in jsreport.templatingEngines.waitForAsyncHelper.
    I will come back here shortly when its more clear to me whats wrong.



  • I was able to fix the problem you found.
    Unfortunately, I don't know exactly when we release a hotfix with this. Likely during the next few weeks.
    If it's possible, try to live with some code duplication till then.
    I apologize for the inconvenience.



  • No problem. We already have duplicate code that I wanted to simplify. Thanks for quick responses ;)


Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.