Reputation: 931
I am using a simple polymer application with few pages in iron-pages. I am uploading a file in one page and then I want to access this uploaded file in another page.
I tried several things but nothing seems to work, here is the sample code
Page in which file is uploaded
<dom-module id="file-upload-page">
<template>
<form method="post" enctype="multipart/form-data" action="/someation" disable-native-validation-ui no-validate>
<my-input file={{file}} id="sampleFileInput" btn-style="primary" max-files="1" accept=".xls, .xlsx" on-drop="fileUploadChangeListener"
label="[[localize('open_invoices_file')]]" help-text="[[localize('open_invoices_file_help')]]" no-auto required>
</my-input>
</form>
</template>
<script>
class FileUploadPge extends Polymer.mixinBehaviors([], Polymer.Element) {
static get is() {
return 'file-upload-page';
}
static get properties() {
return {
}
}
}
customElements.define(FileUploadPge.is, FileUploadPge);
</script>
</dom-module>
Page in which file is accessed
<dom-module id="consumer-page">
<template>
//some code
</template>
<script>
class ConsumerPage extends Polymer.mixinBehaviors([], Polymer.Element) {
static get is() {
return 'consumer-page';
}
constructor() {
super();
}
static get properties() {
return {
//some properties
}
}
ready() {
super.ready();
var temp2 = this.$.sampleFileInput; // returns null
var temp3 = this.shadowRoot.querySelector("#sampleFileInput"); // returns null
var temp4 = this.root.querySelector('#sampleFileInput'); // returns null
var temp5 = this.$$('#sampleFileInput'); // returns null
this._refreshSelections();
};
_proceed() {
var test1 = Polymer.dom(this).querySelector("#sampleFileInput"); // returns null
var test2 = this.$.sampleFileInput; //returns null
var test3 = document.getElementById("sampleFileInput"); //returns null
var test4 = this.$$("sampleFileInput"); //returns null
var test5 = this.shadowRoot; //returns some object
var test6 = this.$$.sampleFileInput; //returns null
var test7 = document.querySelector('sampleFileInput'); //returns null
var test8 = document.querySelector('file-upload-page::shadow .FileUploadPge'); //returns null
var temp4 = this.root.querySelector('#sampleFileInput');//returns null
var temp5 = this.$$('#sampleFileInput');//returns null
var temp6 = this.shadowRoot.querySelector('#sampleFileInput'); // returns null
};
}
customElements.define(ConusmerPage.is, ConusmerPage);
</script>
</dom-module>
The same code works in polymer1.0 with this
document.getElementById("sampleFileInput")
Can somebody help what wrong am I doing in accessing this file in other page, and how can I handle this scenario in Polymer 2.0?
Upvotes: 0
Views: 250
Reputation: 3142
As you said in consumer-page
you're trying to access the #sampleFileInput
element which is a child of another component.
All of these attempts:
var temp2 = this.$.sampleFileInput;
var temp3 = this.shadowRoot.querySelector("#sampleFileInput");
var temp4 = this.root.querySelector('#sampleFileInput');
var temp5 = this.$$('#sampleFileInput');
var test1 = Polymer.dom(this).querySelector("#sampleFileInput");
fail because you're trying to access an element which is not present inside consumer-page
's template, while these:
var test7 = document.querySelector('sampleFileInput');
var test8 = document.querySelector('file-upload-page::shadow .FileUploadPage');
fail respectively because document.querySelector()
cannot select inside shadow dom and ::shadow
and /deep/
selectors were deprecated (see here).
Technically you should be able to select #sampleFileInput
inside consumer-page
this way:
this.parentElement // Goes back to iron-pages
.querySelector('file-upload-page') // Selects file-upload-page
.shadowRoot // Enters its shadow root
.querySelector('#sampleFileInput'); // Selects the file uploader
however accessing elements inside others' shadow root is considered a not so good practice not to mention that if you're using lazy loading for iron-pages
pages this will fail if file-upload-page
wasn't loaded.
There are instead many other ways to expose information outside of custom elements such as events or properties.
You could, if it can fit with your implementation, use the component holding iron-pages
as coordinator of your procedure and use attributes bindings to notify it with the data it needs from the different pages as the user goes on filling.
IE in file-upload-page
bind the uploaded file url to a property, and observe it in the parent:
<iron-pages>
<file-upload-page url="{{url}}"></file-upload-page>
<consumer-page></consumer-page>
</iron-pages>
<script>
class Parent extends PolymerElement {
// ...
static get properties() {
return {
url: {
type: String,
reflectToAttribute: true,
observer: '_urlChanged',
},
};
}
_urlChanged() {
console.log(this.url);
}
// ...
}
</script>
Upvotes: 3