How can I get an HTML element from a template?


This seems like it should be super simple, but for some reason it’s just not working.

I’m trying to upload an image file using ember-cli-form-data. Their doc says to use an input tag with type=file. Then, when the form is submitted, you grab the input element and call element.files[0] to get the specified file. (files is a valid property for a file-type input element).

But for some reason I am unable to get the input element so I can get the file the user specified. Heck, I can’t even get its corresponding label.

I am using a component (don’t know if that makes a difference or not).

Here is what I have in the component’s template:

<label for='456' id='123'>My label</label>
<input type="file" id="456">

Here is what I have in the component’s js file (in the submit action handler):

let  el = document.getElementById('123');
console.log(`getElementById(123): ${JSON.stringify(el)}`);

el = this.$('#123');
console.log(`$(#123): ${JSON.stringify(el)}`);

el = document.getElementById('456');
console.log(`getElementById(456): ${JSON.stringify(el)}`);

el = this.$('#456');
console.log(`$(#456): ${JSON.stringify(el)}`);

As you can see, I have tried two different ways to grab the element.

Here is the output:

getElementById(123): {}
$(#123): {"0":{},"length":1,"prevObject":{"0":{"sizzle1532006154834":{"undefined":{"parentNode":[1027,1,true]}}},"length":1}}
getElementById(456): {} 
$(#456): {"0":{},"length":1,"prevObject":{"0":{"sizzle1532006154834":{"undefined":{"parentNode":[1027,1,true]}}},"length":1}}

As you can see, the document.getElementId() didn’t seem to work at all (this is how the addon’s doc said to do it), and using using a jQuery selector doesn’t give me anything I can call file on. When I tried I got the following error in the console:

TypeError: el.files is undefined

Can someone point out what I am doing wrong, and how I can just grab an element from a component’s template?

Thanks, Larry

getElementById returns an Element or null. JSON.stringify() returns an empty JSON object for native DOM Element without anything special (e.g. jQuery event listeners attached to it). So what you see in your console log is just the difference between JSON.stringify() of a native object and a jQuery object.

Is there any reason for not using the change event of your <input type="files"> and getting the files from the event?

Thanks for the explanation, jelhan.

I finally got it to work. The addon’s documentation was actually correct. I am using ember-paper (which, btw, I like a lot), and unbeknownst to me, when you set something like id='xxx' for a form element, paper changes that id to input-xxx - which sent me down multiple wrong roads, each with their own supply of yaks to shave.

Oh well, wasn’t the first time something like that happened. And, as we all know, it won’t be the last.

Thanks again.

1 Like