I have a js "my_js_file.js" file which I include only into a single page. In that js file I need to get an url by calling a phoenix helper:
# my_js_file.js
function func1(userLogin) {
var createUserUlr = "<%= user_home_path(@conn, :create, userLogin) %>";
//...........
But it doesn't work. When I rename it to "my_js_file.js.eex", it still doesn't work -- the value between "<%= %>" isn't getting evaluated. Why not? And what are the options? Note that I'm passing a variable to the url.
I don't think this is possible, because the assets in the static/
directory are not processed by Elixir, but by your asset pipeline (Brunch by default). They are pre-compiled so even if it worked, you would not have access to the @conn
variable, since this is not available at the time when static assets are compiled.
Keep in mind this is a good thing! The server does not need to re-render your Javascript on every page request.
You have several options to get the desired result:
Might seem hacky, but works well enough for simple cases. I recommend hard coding just a path, using //
at the start to preserve the current protocol (http/https). If you need to resolve this to a full URL, you can use this trick .
For one-off usage, you can add a data attribute to a related portion of your markup, for example for a login form:
<div id="create-user" data-url="<%= user_home_path(@conn, :create, userLogin) %>">
<!-- ... -->
</div>
Then in your JavaScript, you can access the data attribute. Note that depending on your use case, there might be a better way to retrieve the DOM node containing the data attribute than using document.querySelector
, this is just an example:
let createUserUrl = document.querySelector("#create-user").getAttribute("data-url");
If you only need to target IE11+ or willing to use a polyfill , you can also use dataset
let createUserUrl = document.querySelector("#create-user").dataset.url;
Or if you're using jQuery:
let createUserUrl = $("#create-user").data("url");
Maybe you'll be able to extract the URL from a different attribute such as the url
of a form
, should you be overriding the onclick
handler of the submit button, for example.
window
object For truly global values, such as authentication tokens etc. you can set a property on the window
object, for example in web/templates/layout/app.html.eex
<script>window.userToken = "<%= assigns[:user_token] %>";</script>
then in your JavaScript, you can simply access
window.userToken
There are also more advanced solutions available for this problem, including:
Add a separate JSON endpoint that returns the required data as JSON which can then be requested from your JavaScript
If you use a JavaScript framework such as React.js, Vue.js, etc. you might be able to leverage routing logic from the framework or auxiliary JavaScript packages.
I'm sure there's even more options I didn't think of right now.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.