smapiot / piral

Framework for next generation web apps using micro frontends. :rocket:

Home Page:https://piral.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple Angular Extensions params

prepfarm opened this issue · comments

Bug Report

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Environment Details and Version

Piral 1.4.3
Angular 17

Description

If you have two or more of the same Angular extensions on the same page with different params, logging params from the extension will log params that are passed down for first extension.

Steps to Reproduce

  1. Have a registered page with multiple extensions
piral.registerPage('/sample', () => (
    <>
      <piral.Extension
        name="angular-pilet"
        params={{ foo: '1' }}
      />
      <piral.Extension
        name="angular-pilet"
        params={{ foo: '2' }}
      />
    </>
  ));
  1. Log params in extension
constructor(
    @Inject('Props') public componentProps: ExtensionComponentProps<any>
  ) {
    console.log(componentProps.params.foo);
  }

Expected behavior

It will log { foo: '1' } twice.

Actual behavior

It should log { foo: '1' } and { foo: '2' }

Possible Origin/Solution

When using @Input('Props') and showing foo somewhere inside html, it's working fine, only when using @Inject('Props') Piral is failing to provide params that are passed specifically for other instances of the same extension.

Yeah there is not much we can do. The injection is Angular global - this is one of the reasons we have the @Input (and recommend this one).

Remark: We did not remove @Inject due to backwards compatibility. We don't want pilets to fail just because the app shell updated piral-ng.

(We'll stress this in the docs)

Hi, sorry I'm getting back to you just now. I'm having troubles using the props from @Input. They are really only available in html or with ngOnInit with setTimeout wrapper. And component is not getting notified with new props in ngOnChanges.

Do you have an example somewhere of how to use it inside ngOnInit without setTimeout hack? I have params that should be accessed on initialization inside component.ts.

It's a good question, because @Input was designed / is used for permanent / observed values, while @Inject / constructor logic would be great for such initialization tasks.

What I always like to use is simply a getter / setter for the @Input. This way you essentially create a callback that is called when the input value changes.

Nevertheless, the tip might not be good enough for you if you are forced to use OnInit. I am currently thinking if we could "lift" / "fix" the issue with @Inject. It would still be "unreliable", but reliable enough for constructors (i.e., you'd get the "correct" value once, but - like now - it would then never change / not be reactive. I think this approach could be combined with @Input to have both cases covered, too.