1

I am using the below code to play an audio file for every second, the audio file is a second long and it basically a tick. The code will run only once and then I see the error in the console. My intention is to make it run every second until something is achieve then I can clear the Interval. This is the error I am getting in the console

Uncaught SyntaxError: Unexpected identifier 
setInterval (async)

This is my code:

    $('select[name=notsound]').change(function(){
    var h = $(this).val();
    var tickAudio = new Audio('https://www.sample.com/sounds/'+h+'');
    setInterval(tickAudio.play(),1000);
    });

I am not sure why is this happening, I am sure that I have made some error which is causing this issue, as it was working before I thought of giving it a different approach. Thank you for reading my query. :)

  • 2
    You may want `setInterval(tickAudio.play, 1000)` without the extra `()`, otherwise you'll be calling the result of `tickAudio.play()` every second. – Scott May 10 '18 at 14:44
  • try to pass callback but not it's result `setInterval(tickAudio.play,1000);` – MysterX May 10 '18 at 14:44
  • When I do that I get this error Uncaught (in promise) TypeError: Failed to execute 'play' on 'HTMLMediaElement': Illegal invocation – Milind Pandharkame May 10 '18 at 14:46
  • `setInterval(tickAudio.play(),1000);` => `setInterval(tickAudio.play.bind(tickAudio),1000);` or `setInterval(function() { tickAudio.play(); },1000);`, see the linked question's answers for why. – T.J. Crowder May 10 '18 at 14:47
  • you are using interval/timeout to make sure video is loaded before play(), better to remove it and use load event instead: $('select[name=notsound]').change(function(){ var h = $(this).val(); var tickAudio = new Audio(); tickAudio.onload = function(){ tickAudio.play(); } tickAudio.src ='https://www.sample.com/sounds/'+h+''; }); – Hassan Alhaj May 10 '18 at 14:59

2 Answers2

3

Method play needs to be called in the context of the right object:

var cleartick = setInterval(tickAudio.play.bind(tickAudio),1000);

The second suggestion of @rmlan will also work.

Clearing interval is the same - you need not to call a function, but to pass a function reference to setTimeout:

setTimeout(clearInterval, 3000, cleartick);

setInterval/setTimeout have a convenient way of passing parameters to timer functions - as cleartick above.

Igor
  • 15,833
  • 1
  • 27
  • 32
  • Yes, this works for me and the second suggestion of rmlan as well. The problem is that I am trying to clear the Interval as well. This is what I am doing and it is wrong for sure. var cleartick = setInterval(tickAudio.play.bind(tickAudio),1000);; setTimeout(clearInterval(cleartick), 3000); I am not good at Js. – Milind Pandharkame May 10 '18 at 15:05
  • Thanks! This works for me. :) – Milind Pandharkame May 10 '18 at 15:10
2

You are currently "executing" the result of tickAudio.play() every second, instead of executing the function itself.

To remedy this, you can either pass the function as an object:

setInterval(tickAudio.play.bind(tickAudio),1000);

Or wrap the call in an anonymous function:

setInterval(function () { tickAudio.play() },1000);
rmlan
  • 4,387
  • 2
  • 21
  • 28
  • The second one works and it is looping a tick sound, I am also trying to use the setTimeout to clear the interval after 3 secs. I don't think this is working to clear the interval. var cleartick = setInterval(function () { tickAudio.play() },1000); setTimeout(clearInterval(cleartick), 3000); seems like I am making the same mistake? – Milind Pandharkame May 10 '18 at 15:03
  • This seems like a separate question that you should ask if you are still having trouble. – rmlan May 10 '18 at 15:08