New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Optionality for bootstrap components in NgModule #11730

Closed
chrisnicola opened this Issue Sep 19, 2016 · 13 comments

Comments

Projects
None yet
9 participants
@chrisnicola

chrisnicola commented Sep 19, 2016

I'm submitting a ... (check one with "x")

[x] feature request

Current behavior

Currently as I understand it a single static HTML page can support multiple root components by adding them to the bootstrap array of an NgModule definition.

With Angular 1 it wasn't uncommon for static sites to "sprinkle" directives/components throughout the site with no root application component and no routing.

In theory the same behaviour is almost possible with Angular 2 by adding all of the components used by the static site to the bootstrap section, however on any page that doesn't use a component from that section an error message is given.

main.bundle.js:37866
EXCEPTION: Error in ./SecondComponent class SecondComponent_Host - inline template:0:0 caused by: The selector "app-component" did not match any elements

Expected behavior

As a result of trying this, it occurred to me that it might be useful to allow for optionality of bootstrap components in a module. This would help some people with Angular 1 => 2 migrations potentially.

Reproduction of the problem

Minimal demo is trivial with a simple angular-cli app. Add a second component and add it to declarations and bootstrap in the main NgModule then try loading the page with the second component both declared and not declared in index.html.

Happy to push an example to Github if needed though.

What is the motivation / use case for changing the behavior?

As described above, the main motivation is to support "sprinkling" components (possibly also directives) in static websites that don't require the entire site to be rendered as a SPA.

One current workaround to support this without error messages is simply creating a single root module per independent static page. This isn't an unreasonable solution right now so I wanted to mention it. It is somewhat less convenient though for packaging purposes.

  • Angular version: 2.0.0

  • Browser: [all]

  • Language: [all]=

@robwormald

This comment has been minimized.

Member

robwormald commented Sep 19, 2016

You can do this already by omitting the bootstrap option, and implementing ngDoBootstrap() yourself - see this example https://plnkr.co/edit/J6CRzEL4GS2TxGXDkBnC?p=preview

Does that cover your use case?

@vicb

This comment has been minimized.

Contributor

vicb commented Sep 19, 2016

@robwormald thanks !

Do you know if this is documented on angular.io (or if there is an issue) ?

@chrisnicola

This comment has been minimized.

chrisnicola commented Sep 20, 2016

@robwormald interesting, I was wondering whether the NgModule decorated classes had any hooks or functional purpose as most examples have them just empty. It definitely seems undocumented at the moment: https://angular.io/docs/ts/latest/api/core/index/NgModule-interface.html

However, this doesn't really address the use case above. Whether you bootstrap the components in decorator or in the ngDoBootstrap hook they are required and an error will be thrown if it doesn't find the component in the page.

You can see what I mean here, where I've removed one of the bootstrapped components from index.html. Open the console and you'll see the error.

https://plnkr.co/edit/qZsdWCbh5YOGojS2NvC7?p=preview

@MyTotoro

This comment has been minimized.

MyTotoro commented Sep 20, 2016

I agree with @chrisnicola - the current behaviour is not optimal, it was odd to see this at first and I spent a bit of time going through my code and trying to debug it

Unfortunately this thread/post isn't at the top of the google search results so it took me a few attempts at searching.

creating a single root module per independent static page.

I'm still learning Angular but this seems a bit heavy?

@chrisnicola

This comment has been minimized.

chrisnicola commented Sep 20, 2016

This functionality has been discussed elsewhere a couple of times in the past. I previously asked about it on SO, but it was still early in Angular 2 development so I decided to wait a bit. It was also asked about on /r/Angular2

http://stackoverflow.com/questions/35418243/sprinkling-angular-2-components-inside-a-non-angular-page

https://www.reddit.com/r/Angular2/comments/424nwn/using_angular_2_without_it_being_a_single_page_app/

@chrisnicola

This comment has been minimized.

chrisnicola commented Sep 21, 2016

@robwormald so based on the example here I should at least be able to do this with a Hybrid Angular 1 + 2 app.

However at the moment that doesn't seem to work. The Angular 2 components are not rendered unless they themselves are bootstrapped by adding them to bootstrap in NgModule and passing it to platformBrowserDynamic. I take it this isn't intended?

Edit: Sorry my mistake I forgot that I also had to downgrade the Angular 2 component for it to work. So yes this does work but only for an Angular 1 app running downgraded Angular 2 components.

@tbosch

This comment has been minimized.

Member

tbosch commented Oct 10, 2016

@chrisnicola So to conditionally bootstrap components, just do a querySelector before calling appRef.bootstrap(App); to check whether the component is already on the page.

We do want to continue to fail/report an error if the bootstrap component is not found as this is what most users want.

@tbosch tbosch closed this Oct 10, 2016

@chrisnicola

This comment has been minimized.

chrisnicola commented Oct 11, 2016

@tbosch thanks, not really an ideal solution though, but it can work. I'm not sure why most users would want it that way, but I'll take your word for it.

I will say that considering it is still very early days and I've already located a few examples where people are asking how to do this, so I suspect that it would make sense to allow optional bootstrap components with some method that is easier and more documented than this.

@jpgcode

This comment has been minimized.

jpgcode commented Dec 15, 2016

I'm looking for the same. Adding the components in @NgModule bootstrap works good when the selector is present in the page. In non-SPA the selector could NOT be in there, so it would be good to have a documented way to bootstrap components optionally.

@tbosch Can you provide an example in plunkr on how to do it correctly using @NgModule?
@chrisnicola have you found a solution?

@chrisnicola

This comment has been minimized.

chrisnicola commented Dec 15, 2016

@jpgcode as @tbosch mentioned you can do it by manually bootstrapping using a querySelector to check for the selector and then bootstrap if it is found. This is a bit awkward though and I would argue it is not very ergonomic @tbosch. I do hope this is something that could potentially be addressed in a future Angular release.

@jpgcode it would probably be feasible to make this a bit more transparent with a specialized bootstrapper similar to the one that exists for ngUpgrade. I may see if I can put something together in the near future and contribute it back as a permanent solution to the angular project.

@dietergeerts

This comment has been minimized.

dietergeerts commented Jan 17, 2017

I also need this feature. I always use toolkits for my applications, so I can test and play with the styling and ui components separate from my app. Using Angular 2 for those components make my whole toolkit setup useless (I use https://github.com/dietergeerts/fabricator-builder for it). On toolkit pages, I want to just add components like button, or datepicker, and test how they work etc.... This is now not possible with Angular 2, and I loose the functionality of templating in my toolkit. Please consider changing this so we can bootstrap the page itself for such things. @tbosch .

@Moncef12

This comment has been minimized.

Moncef12 commented Jan 20, 2017

+1
Is it possible to consider A2 more for all the web sites that want to use it ? @tbosch.

@kouasda

This comment has been minimized.

kouasda commented Jan 31, 2017

Ng2 is awesome !!
Here I've used the browser DOM (document) object to implement this conditional bootstrapping: https://plnkr.co/edit/pscwfzj6aaih8BbyrTZ5?p=preview

Hope it would save a lot of time for developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment