Components: FR: YouTube / Google Maps should load the API itself

Created on 10 Sep 2019  Â·  10Comments  Â·  Source: angular/components

Feature Description

I wish the new Youtube package would load the API itself, so we can use the component directly without wrapping it in our own component.

P3 google-maps youtube-player feature has pr needs discussion

Most helpful comment

I also find it unexpected that the player requires app developers to manually load the youtube api. Maybe provide a .forRoot() or .init() static method on the YouTubePlayerModule that will optionally download the youtube player api.

All 10 comments

I also find it unexpected that the player requires app developers to manually load the youtube api. Maybe provide a .forRoot() or .init() static method on the YouTubePlayerModule that will optionally download the youtube player api.

I also find it unexpected that the player requires app developers to manually load the youtube api. Maybe provide a .forRoot() or .init() static method on the YouTubePlayerModule that will optionally download the youtube player api.

Maybe a .forChild() method, imported in modules will be better for lazy-loaded routes/modules ? This method could check the YouTube loading with the YT global variable I guess.

@IgorMinar is your preferred approach to add .forRoot() method to the YouTubePlayerModule?
If so, I'd love to make a PR.

_reposting my comment from Kristiyan's PR_

I'm still quite leery of adding an API that loads the API for you. My rationale is along the lines of:

  • This isn't something we do for any other dependency.
  • I generally think developers should be aware of how they're loading deps into their application, and I'm not a fan of having a black-box API that obscures that.
  • Having an API for loading the dependency implies that there's a "correct" way to do it, when it depends somewhat on what the app wants to do.
  • It's easier for apps to end up in a state with multiple versions of the dependency loaded.
  • Such an API would inherently modify browser global state, which could be problematic in instances where applications want to bootstrap multiple Angular applications. I know we haven't been the best about this before, so it's something that comes to mind now.

The thing I don't have a strong insight into is how painful this is for application developers. To me it seems normal/expected/straightforward to manage a dependency like this, but it's possible I'm missing some nuance here.

@jelbourn how about if you provide a built-in way to initialize it if you provide some InjectionToken which provides some good defaults and whatever common fields people usually tweek when loading the YT API, and if there's no provider for that injection token (which would be something like InjectionToken<YouTubeApiConfig> or whatever), you do nothing.

This way you keep backward compatibility with... not doing anything by default, and provide a new way to initialize it.

What makes providing an injection token simpler than directly adding the dependency?

@jelbourn TL;DR - I agree with you. However, I'll still keep the thoughts I've written down as I've thought and researched for an answer.


I looked at the docs, and it seems that there isn't even an API key involved or something, just loading a script tag with the correct source.

Honestly, looking at it, I think it's legit that the package would load itself because it would make the module act more self-contained.

If I load the module - I get the API. If I don't? I don't.

For me, it feels like not doing this sort of doesn't align with angular-y values, at least in my understanding.

If every angular package that uses some external api that needs a script-tag to load would require you to add the script tag to the index.html itself, it would feel kinda shitty.

I guess it comes down to that – as a consumer, I would expect the module to behave that way, just a matter of intuition.
Whether there are other, technical, points to consider, is another thing.

If I were to design this API, I would strive for this behavior, ofc unless there's a meaningful reason not to do it.


I re-read the issue thread, and I understand your point. Unfortunately, I don't have a lot of insight as to how this kind of dependency is usually managed, and I, therefore, disclaim my points above to being relevant to my experience with such APIs.


I went ahead and looked at the google-maps module, and it seems that it is expected of developers to add the script tag themselves.

Given that, I think it's fair to say that it's better to align with the rest of the package(s).

I would, however, improve the docs on the readme. In the google-maps package, there's a simple snippet to add to your HTML file. Where's in the youtube api docs, they do it imperatively via the dom api.

It's small, but I feel it would be an improvement and would reduce the barrier of entry, that is - if you look at this issue as describing a barrier of entry.

However, if at any point other packages would do the opposite, and do provide a .forRoot, I still think that it's the angular-y thing to do.

Cross-posting my comment from #21401 since the discussion has moved here:

@jelbourn I think that your points are valid, but here's why I decided to do it:

  1. Getting the loading "right" can be tricky, because you'd have to coordinate it between inserting the script with the DOM API and keeping the component from initializing through something like ngIf. It's much easier to do it once on our end.
  2. If you want to load the API yourself only when the component is used, you'll either have repeat some logic or write a wrapper component which means that you'd have to forward all the inputs.
  3. The only way to consume the API is through a script pointing to the Google CDN. As far as I'm aware, there's no option to host it yourself, unless you copy the script somewhere, but then it can break on you at any time.

Regarding your points:

This isn't something we do for any other dependency.

I was planning to do something similar for the Google Maps API, if we managed to agree how this one would be handled, since it's set up in the exact same way.

I generally think developers should be aware of how they're loading deps into their application, and I'm not a fan of having a black-box API that obscures that.

I think that's fair for something like Angular or jQuery where there are different versions and ways to load the code. In the YouTube case, this is the only way of doing it since our component is tightly coupled to the iframe API.

Having an API for loading the dependency implies that there's a "correct" way to do it, when it depends somewhat on what the app wants to do.

As I mentioned above, in this particular case there is only one way of loading the API. The only decision is between loading it up-front or doing so lazily and I'd argue that doing it lazily is preferable.

It's easier for apps to end up in a state with multiple versions of the dependency loaded

As far as I'm aware, there is only one possible version. There's a risk of including the script tag multiple times, but our code should account for that.

I was thinking about this more while I was lying in bed over the weekend. I think the root of my hesitance here is that the YouTube API (and the Google Maps API) use the "old school" way of managing dependencies (drop in a script tag), while Angular lives in the modern world of ECMAScript modules. By deferring the dependency management to the app, we don't tie ourselves into the old school style at all. This keeps the door open to someday moving to directly importing the APIs we use if YouTube/Maps ever start publishing their APIs to npm (I have zero clue whether this would happen). So maybe I can go try to track down an answer from those API owners as to whether this is likely, and make a decision having that knowledge.

note: updating this issue to cover discussion for both google-maps and youtube-player, since I think it's the same argument either way

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vanor89 picture vanor89  Â·  3Comments

theunreal picture theunreal  Â·  3Comments

MurhafSousli picture MurhafSousli  Â·  3Comments

shlomiassaf picture shlomiassaf  Â·  3Comments

constantinlucian picture constantinlucian  Â·  3Comments