party-ring
party-ring

Reputation: 1871

Button onclick handler does not find function declare in javascript file - Laravel Mix

I have encountered a problem numerous times where I cannot get an onclick function in an external js file to work in my Laravel projects. Here is an example from my page source:

<button onclick="testMe()">test</button>
<script type="text/javascript" src="http://[myurl]/js/jobs.js"></script>

Inside jobs.js:

function testMe() {
    console.log('i have appeared');
}

This example is from having my script tag be called AFTER I call on click. I have also tried adding the script BEFORE I call on click. I have also tried adding it to my <head>, but the following error still persists:

Uncaught ReferenceError: testMe is not defined at HTMLButtonElement.onclick

I understand that it cannot find the function, but what else can I try to problem solve this? Is it possible to call onclick to an external JS file?

Edit:

Here is the relevant line of my webpack file:

.js('resources/js/jobs/jobs.js', 'public/js/jobs.js')

How I actually call it (opposed to how it looks viewing the page src):

<script type="text/javascript" src="{{ asset('js/jobs.js') }}"></script>

This is also definitely being brought in because I have a console log above the function, which is being logged to the console.

Upvotes: 1

Views: 2047

Answers (2)

gbalduzzi
gbalduzzi

Reputation: 10176

When you use laravel mix or webpack, those pre-processor create a new 'scope' for every file to avoid naming conflict between different files.

So, the function testMe() is declared inside the jobs.js file, but it is not accessible from the outer scope.

You have 2 options:

  1. Attach the function testMe to the outer scope.

In a browser, the 'root' scope is the window object. So you can attach your function to the window object, and it will be accessible from your HTML elements:

function testMe() {
    console.log('i have appeared');
}
window.testMe = testMe

This is probably the easiest way to get it working, but if you have a lot of functions it would pollute the whole scope

  1. Attach the handler from javascript instead of using onClick html attribute.

Instead of using the onClick HTML attribute, you can set testMe as the click handler from the javscript file itself:

<button id="test-button">test</button>
function testMe() {
    console.log('i have appeared');
}

document.getElementById('test-button').addEventListener('click', testMe)

Upvotes: 10

Nikola Vanevski
Nikola Vanevski

Reputation: 44

The external JS file needs to be loaded before you call the method. There is no guarantee that the external JS file will be loaded at the time of clicking the button, so creating a local wrapper may be a better idea. The local wrapper should check if the remote script has loaded (see this link to see how to do it.

Upvotes: 1

Related Questions