Adding javascript and google api

So this is a bit embarrassing, I assume that what I am trying to do is super basic, but I’ve been looking around for half a day now and have to admit I’m kind of stuck, web development is not my strong suit.

I have a web page that shows (among other things) a map made using google’s map api. At the moment, all javascript is inside script-tags inside app.html.ex, this includes the google maps api url"

I was happy to see that this worked straight away, but it seems suboptimal (both phoenix and heroku seem to believe that this is a bad practice in general), so I want to move it and do it properly.

But how? I added the js code to assets/js/map.js, where do I add the api key? How do I get that javascript to run inside app.html.eex (something about importing in app.js, I am playing around with this now). And lastly, the javascript relies on a few values that I now send to app.html.eex using the controller, which I access in there with <%= for event <- @events do %>. How do I pass those values to the js file?

Once again, I feel a bit bad asking this because I assume it must be the most common question here, but I just can’t seem to find anything that helps me.

If I understand you correctly you’ve used a CDN link script tag like <script src="https://some-cdn/script"/> and then called the library from window using inline JS. You now want to switch to distributing the script yourself, rather than using the CDN, by bundling the script with your app.

I would very much disagree that using JS distributed by CDN is a bad idea. Your approach is just fine, and how many libraries are designed to work. There are some strong benefits to using CDN files, including the fact that it becomes more likely that clients already have that file cached from some other site and your page will load faster.

Nothing in using CDN links vs bundling with webpack is technically Phoenix specific. If you want to learn more about how to use webpack I suggest reading the webpack documentation. There’s a lot to dig into there and you probably need to cross that bridge if you want to build larger more complex client side applications.

Personally I’d avoid managing the file myself in this case and rely on the CDN link. The library is intended to work that way!

Thank you for response!
I was maybe a bit unclear. I am very satisfied with using the CDN link, that is not a problem at all!

My problem is that the rest of the javascript, the things I wrote myself, are now embedded inside app.html.eex, which does not seem to be the right way to go about things. I am looking for a way to remove my javascript from there and let it live inside its own file.

I am mentioning the google script source as the javascript needs to be able to access it somehow!

This may be of some help towards discovering what steps need to be taken:

If you’ve still got the <script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script> in your app.html.eex you can move your JS into that file (assets/js/app.js). You mentioned needing some data from the controller, one simple way of “sharing” this with the JS is putting your code in a function and calling it from the template.

Something like this in the JS file = (data) => {
  // put your code here

And then call it from your controller template

<script><%= your_data %>);

This is a very simplistic version, you can arrange and extend it any way you want. Note again that none of this is Phoenix specific, you could do it this way in any web framework.

A big part of my confusion was that I didn’t know webpack was a thing, once I realized that’s what I should be using it went fairly smoothly from there. At least that part!

Thank you for the links to the gmaps project and example, they will be a handy reference for sure.
And thanks for the sample code, it works like it should! I might do things a bit different now but at least it works!

1 Like

You might also look at the post on JavaScript Explained for Dinosaurs:

I thought Dinosaurs was referring to old folks like me at first, but thankfully it means actual Dinosaurs, and works well for lots of people too. So I guess I can go back to being “wise”.