16

I have 3 root components that get bootstrapped by the root AppModule.

How do you go about specifying an @Input() parameter to one of those components?

Neither

<app-modal [id]="'hard-coded value'"></app-modal>
<app-modal [id]="constantExportedByAppmodule"></app-modal>

are picked up by AppModalComponent:

@Input() id: string;

It is undefined.

jenson-button-event
  • 18,101
  • 11
  • 89
  • 155

2 Answers2

36

As far as I know, you can not pass @Input() to a bootstraped component.

But you can use another way to do that - pass the value as an attribute.

index.html :

<my-app myAttribute="myAttributeValue">
    <div>Loading...</div>
</my-app>

app.component.ts :

@Component({
    selector: 'my-app',
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.css']
})
export class AppComponent {
    constructor(private elementRef:ElementRef) {
        let myAttribute = this.elementRef.nativeElement.getAttribute('myAttribute');
    }
}
Grégory Gossart
  • 817
  • 7
  • 15
  • What is a good way to use this method safely? "Permitting direct access to the DOM can make your application more vulnerable to XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the [Security Guide](http://g.co/ng/security)." – mrClean Oct 18 '17 at 20:24
  • 3
    This is the only thing I can think of: `this.myattribute = this.sanitizer.sanitize(SecurityContext.HTML, this.elementRef.nativeElement.getAttribute('myattribute'))` – mrClean Oct 18 '17 at 20:30
  • Its worth remembering that these come in as strings, so you will need to fiddle them if you want boolean/numbers etc – t0mmyw Feb 20 '19 at 09:16
5

As @Grégory Gossart said you can not pass @Input data as normal for bootstraped components.

It is because an @Input is expected to come from an angular component. So, If your root app is loaded/bootstraped directly in the HTML it has not reference of what Is gonna provide that @Input, I thought.

As good practice commented on many Angular docs, and probably because it specific behaviours, you should only bootstrap one root App. I think your option here is add a root app which you bootstrap and it imports your others(3) and use those as template in it. Then pass the @Input as normal. Really nothing special.

I think another option could be pass the data from an @Injectable to your root apps if you decide you need to bootstrap all them and need external data. But I feel it is more refered to specific purposes.

Edit: I took a time to find this blog I have read past day and reason why I said about @Injectable. So merits to the author, but interesting stuff. Providing external data when bootstrapping Angular 2

Sam
  • 1,459
  • 1
  • 18
  • 32
  • 5
    we're adding angular components into various places in a legacy asp.net web form monolith as a basis for refactor. at this stage one root component is not an option without rewriting the whole lot in one go. – jenson-button-event Sep 20 '17 at 09:04