# Does anyone have tips on playing audio in JS/Elm?

**URL:** <https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596>\
**Category:** Learn\
**Created:** [November 2, 2019, 8:18am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596 "2019-11-02T08:18:28Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![David\_Legard](https://avatars.discourse-cdn.com/v4/letter/d/e79b87/32.png) [@David\_Legard](https://discourse.elm-lang.org/u/David_Legard)\
**Post date:** [November 2, 2019, 8:18am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/1 "2019-11-02T08:18:28Z")

</div>

I figured this would be fairly simple using ports.

In the Elm port module, I simply set up an outgoing port:

`port play : String -> Cmd msg --string is the filename of the audio file`

and in the JS

```
var app = Elm.Main.init({node: document.getElementById('elm')});
app.ports.play.subscribe(function(fn) {   
    var audio = new Audio(fn);
    audio.play();
  });

```

Yet the console immediately shows me an error message (in the `app.ports.play` line) of

`Uncaught TypeError: Cannot read property 'play' of undefined`.

The rest of the embedded Elm works fine, but I can’t find a way past this one.

Any tips gratefully received.

---

<div class="post-metadata">

**Author:** ![catz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/catz/32/1007_2.png) [@catz](https://discourse.elm-lang.org/u/catz)\
**Post date:** [November 2, 2019, 8:39am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/2 "2019-11-02T08:39:42Z")

</div>

Hello, are you sure you run play function somewhere in your elm code? Looks like compiler didn’t put play function into the output bundle.

---

<div class="post-metadata">

**Author:** ![David\_Legard](https://avatars.discourse-cdn.com/v4/letter/d/e79b87/32.png) [@David\_Legard](https://discourse.elm-lang.org/u/David_Legard)\
**Post date:** [November 2, 2019, 8:47am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/3 "2019-11-02T08:47:49Z")

</div>

Yes, it’s all in there.

in the view function

…  
`button [onClick Play] [text "Play >"]`  
…

in the update function

…  
`Play -> (model, play (sourceFromItem model.currentItem))`  
…

It fails on the page load, not on the click of the button.

---

<div class="post-metadata">

**Author:** ![catz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/catz/32/1007_2.png) [@catz](https://discourse.elm-lang.org/u/catz)\
**Post date:** [November 2, 2019, 9:08am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/4 "2019-11-02T09:08:48Z")

</div>

Well, check this article on contentloaded. [https://thoughtbot.com/blog/bridging-elm-and-javascript-with-ports](https://thoughtbot.com/blog/bridging-elm-and-javascript-with-ports)

---

<div class="post-metadata">

**Author:** ![David\_Legard](https://avatars.discourse-cdn.com/v4/letter/d/e79b87/32.png) [@David\_Legard](https://discourse.elm-lang.org/u/David_Legard)\
**Post date:** [November 2, 2019, 9:15am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/5 "2019-11-02T09:15:43Z")

</div>

Thanks - I’d read that and it was one of the places I borrowed some structure from.

It’s no biggie - I can do the whole thing in HTML/JS, it would just be nicer in Elm.

---

<div class="post-metadata">

**Author:** ![lydell](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lydell/32/178_2.png) [@lydell](https://discourse.elm-lang.org/u/lydell)\
**Post date:** [November 2, 2019, 9:39am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/6 "2019-11-02T09:39:34Z")

</div>

Hi!

Your approach looks good! (I’d just rename the `fn` parameter in your JS to `url` to make things less confusing.)

The error you’ve encountered does not seem to have anything to do with audio, though!

If the compiler does not detect any ports being used in your program at all, it won’t even define `.ports` on your `app`. So when you try to call `app.ports.play.subscribe()` on page load, it fails to read `.play` because `app.ports` does not exist.

Now, it _sounds_ like you do have defined and used a port, but it’s hard to tell what’s actually going on without seeing the full picture.

---

<div class="post-metadata">

**Author:** ![David\_Legard](https://avatars.discourse-cdn.com/v4/letter/d/e79b87/32.png) [@David\_Legard](https://discourse.elm-lang.org/u/David_Legard)\
**Post date:** [November 2, 2019, 9:49am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/7 "2019-11-02T09:49:57Z")

</div>

Thanks. Yes, this is beyond me.

I have defined type `Msg = NoOp | ChangeName | Play`, but the compiled JS for the update function doesn’t seem to include the Play msg, and I have no idea how to add it in.

```
var $author$project$Main$update = F2(
	function (msg, model) {
		switch (msg.$) {
			case 'NoOp':
				return model;
			case 'ChangeToName':
				var s = msg.a;
				return _Utils_update(
					model,
					{
						currentItem: A2($author$project$Kontent$findItemFromTitle, s, model.kontent)
					});
			default:
				return model;
		}
	});
```

---

<div class="post-metadata">

**Author:** ![David\_Legard](https://avatars.discourse-cdn.com/v4/letter/d/e79b87/32.png) [@David\_Legard](https://discourse.elm-lang.org/u/David_Legard)\
**Post date:** [November 2, 2019, 10:12am UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/8 "2019-11-02T10:12:56Z")

</div>

All a bit baffling, but I refactored some code and the compiled Play function appeared.

---

<div class="post-metadata">

**Author:** ![berend](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/berend/32/2250_2.png) [@berend](https://discourse.elm-lang.org/u/berend)\
**Post date:** [November 3, 2019, 8:04pm UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/9 "2019-11-03T20:04:26Z")

</div>

Why not simply use the HTML5 audio element? Works perfectly fine.

---

<div class="post-metadata">

**Author:** ![David\_Legard](https://avatars.discourse-cdn.com/v4/letter/d/e79b87/32.png) [@David\_Legard](https://discourse.elm-lang.org/u/David_Legard)\
**Post date:** [November 3, 2019, 11:52pm UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/10 "2019-11-03T23:52:23Z")

</div>

The reason was that I’m not playing a specified file, but a user-selectable file (in Elm), the filename being sent via ports to JS.

I have it working OK now, the problem was caused by my deliberate forgetting of Javascript and its ways.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [November 13, 2019, 11:52pm UTC](https://discourse.elm-lang.org/t/does-anyone-have-tips-on-playing-audio-in-js-elm/4596/11 "2019-11-13T23:52:27Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
