Triggering a click() on a child component's file input won't work from a subscription
Consider a component of which the template include a file input. The input can be opened by calling a public open()
method which triggers a click on the nativeElement
of the input.
@Component({
selector: 'child',
template: '<input type="file" #input/>',
})
export class ChildComponent {
@ViewChild('input')
public input: ElementRef;
public open(): void {
console.log('OPENING THE FILE INPUT');
this.input.nativeElement.click();
}
}
This ChildComponent
is called in a ParentCompenent
, which calls ChildComponent.open()
in multiple contexts, as defined below :
@Component({
selector: 'parent',
template: '<child></child>',
})
export class ParentComponent {
@ViewChild(ChildComponent)
public child: ChildComponent;
constructor( private parentService: ParentService ) {
}
public openChildInput(): void {
// This works.
// Output:
// OPENING THE FILE INPUT
// The file input opens
this.child.open();
}
public waitAndOpenChildInput(): void {
parentService.wait()
.subscribe( () => {
// This does not work.
// Output:
// "OPENING THE FILE INPUT"
// The file input DOES NOT open...
this.child.open();
})
}
}
In both cases, calling the open()
method seems to work (as the console.log
does show); yet the file input seems unwilling to open itself when called from a subscription.
Any ideas why ?
Thanks in advance...
angular rxjs
add a comment |
Consider a component of which the template include a file input. The input can be opened by calling a public open()
method which triggers a click on the nativeElement
of the input.
@Component({
selector: 'child',
template: '<input type="file" #input/>',
})
export class ChildComponent {
@ViewChild('input')
public input: ElementRef;
public open(): void {
console.log('OPENING THE FILE INPUT');
this.input.nativeElement.click();
}
}
This ChildComponent
is called in a ParentCompenent
, which calls ChildComponent.open()
in multiple contexts, as defined below :
@Component({
selector: 'parent',
template: '<child></child>',
})
export class ParentComponent {
@ViewChild(ChildComponent)
public child: ChildComponent;
constructor( private parentService: ParentService ) {
}
public openChildInput(): void {
// This works.
// Output:
// OPENING THE FILE INPUT
// The file input opens
this.child.open();
}
public waitAndOpenChildInput(): void {
parentService.wait()
.subscribe( () => {
// This does not work.
// Output:
// "OPENING THE FILE INPUT"
// The file input DOES NOT open...
this.child.open();
})
}
}
In both cases, calling the open()
method seems to work (as the console.log
does show); yet the file input seems unwilling to open itself when called from a subscription.
Any ideas why ?
Thanks in advance...
angular rxjs
4
Can you reproduce the problem in a stackblitz?
– ConnorsFan
Nov 14 '18 at 17:33
Does it work if you dosetTimeout(()=>this.child.open(),0)
instead?
– Aviad P.
Nov 14 '18 at 18:12
we need to see the service too so as @ConnorsFan said it would be nice to have a stackblitz
– Kevin ALBRECHT
Nov 14 '18 at 18:13
please paste the relevant content ofParentService
– ggradnig
Nov 14 '18 at 18:24
add a comment |
Consider a component of which the template include a file input. The input can be opened by calling a public open()
method which triggers a click on the nativeElement
of the input.
@Component({
selector: 'child',
template: '<input type="file" #input/>',
})
export class ChildComponent {
@ViewChild('input')
public input: ElementRef;
public open(): void {
console.log('OPENING THE FILE INPUT');
this.input.nativeElement.click();
}
}
This ChildComponent
is called in a ParentCompenent
, which calls ChildComponent.open()
in multiple contexts, as defined below :
@Component({
selector: 'parent',
template: '<child></child>',
})
export class ParentComponent {
@ViewChild(ChildComponent)
public child: ChildComponent;
constructor( private parentService: ParentService ) {
}
public openChildInput(): void {
// This works.
// Output:
// OPENING THE FILE INPUT
// The file input opens
this.child.open();
}
public waitAndOpenChildInput(): void {
parentService.wait()
.subscribe( () => {
// This does not work.
// Output:
// "OPENING THE FILE INPUT"
// The file input DOES NOT open...
this.child.open();
})
}
}
In both cases, calling the open()
method seems to work (as the console.log
does show); yet the file input seems unwilling to open itself when called from a subscription.
Any ideas why ?
Thanks in advance...
angular rxjs
Consider a component of which the template include a file input. The input can be opened by calling a public open()
method which triggers a click on the nativeElement
of the input.
@Component({
selector: 'child',
template: '<input type="file" #input/>',
})
export class ChildComponent {
@ViewChild('input')
public input: ElementRef;
public open(): void {
console.log('OPENING THE FILE INPUT');
this.input.nativeElement.click();
}
}
This ChildComponent
is called in a ParentCompenent
, which calls ChildComponent.open()
in multiple contexts, as defined below :
@Component({
selector: 'parent',
template: '<child></child>',
})
export class ParentComponent {
@ViewChild(ChildComponent)
public child: ChildComponent;
constructor( private parentService: ParentService ) {
}
public openChildInput(): void {
// This works.
// Output:
// OPENING THE FILE INPUT
// The file input opens
this.child.open();
}
public waitAndOpenChildInput(): void {
parentService.wait()
.subscribe( () => {
// This does not work.
// Output:
// "OPENING THE FILE INPUT"
// The file input DOES NOT open...
this.child.open();
})
}
}
In both cases, calling the open()
method seems to work (as the console.log
does show); yet the file input seems unwilling to open itself when called from a subscription.
Any ideas why ?
Thanks in advance...
angular rxjs
angular rxjs
asked Nov 14 '18 at 17:30
Alexis FacquesAlexis Facques
847314
847314
4
Can you reproduce the problem in a stackblitz?
– ConnorsFan
Nov 14 '18 at 17:33
Does it work if you dosetTimeout(()=>this.child.open(),0)
instead?
– Aviad P.
Nov 14 '18 at 18:12
we need to see the service too so as @ConnorsFan said it would be nice to have a stackblitz
– Kevin ALBRECHT
Nov 14 '18 at 18:13
please paste the relevant content ofParentService
– ggradnig
Nov 14 '18 at 18:24
add a comment |
4
Can you reproduce the problem in a stackblitz?
– ConnorsFan
Nov 14 '18 at 17:33
Does it work if you dosetTimeout(()=>this.child.open(),0)
instead?
– Aviad P.
Nov 14 '18 at 18:12
we need to see the service too so as @ConnorsFan said it would be nice to have a stackblitz
– Kevin ALBRECHT
Nov 14 '18 at 18:13
please paste the relevant content ofParentService
– ggradnig
Nov 14 '18 at 18:24
4
4
Can you reproduce the problem in a stackblitz?
– ConnorsFan
Nov 14 '18 at 17:33
Can you reproduce the problem in a stackblitz?
– ConnorsFan
Nov 14 '18 at 17:33
Does it work if you do
setTimeout(()=>this.child.open(),0)
instead?– Aviad P.
Nov 14 '18 at 18:12
Does it work if you do
setTimeout(()=>this.child.open(),0)
instead?– Aviad P.
Nov 14 '18 at 18:12
we need to see the service too so as @ConnorsFan said it would be nice to have a stackblitz
– Kevin ALBRECHT
Nov 14 '18 at 18:13
we need to see the service too so as @ConnorsFan said it would be nice to have a stackblitz
– Kevin ALBRECHT
Nov 14 '18 at 18:13
please paste the relevant content of
ParentService
– ggradnig
Nov 14 '18 at 18:24
please paste the relevant content of
ParentService
– ggradnig
Nov 14 '18 at 18:24
add a comment |
1 Answer
1
active
oldest
votes
For security reasons, it is not possible in modern browsers to programatically invoke the click
event on a file input - UNLESS it happens during a user interaction. Otherwise, websites and ads could spam users with file dialoges without them interacting with the page and e.g. have them unknowingly upload a file.
The issue with using an Observable is that, if it is asynchronous (i.e. when using the async
scheduler), you leave the user interaction context and the browser will not open the file dialog.
You can solve this only by making your Observable synchronous (which, actually, almost all preset Observables are). If you have e.g. a HTTP request, this won't be possible and you have to look for alternatives for opening the file dialog (though I'm not sure if any of those would work in your setup).
Here is an GitHub issue that is similiar to your problem with an explanation:
Therefore [due to the asynchronity], the click() call [...] is not triggered by a user-event, from Chrome's perspective, and consequently is ignored.
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305778%2ftriggering-a-click-on-a-child-components-file-input-wont-work-from-a-subscri%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
For security reasons, it is not possible in modern browsers to programatically invoke the click
event on a file input - UNLESS it happens during a user interaction. Otherwise, websites and ads could spam users with file dialoges without them interacting with the page and e.g. have them unknowingly upload a file.
The issue with using an Observable is that, if it is asynchronous (i.e. when using the async
scheduler), you leave the user interaction context and the browser will not open the file dialog.
You can solve this only by making your Observable synchronous (which, actually, almost all preset Observables are). If you have e.g. a HTTP request, this won't be possible and you have to look for alternatives for opening the file dialog (though I'm not sure if any of those would work in your setup).
Here is an GitHub issue that is similiar to your problem with an explanation:
Therefore [due to the asynchronity], the click() call [...] is not triggered by a user-event, from Chrome's perspective, and consequently is ignored.
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
add a comment |
For security reasons, it is not possible in modern browsers to programatically invoke the click
event on a file input - UNLESS it happens during a user interaction. Otherwise, websites and ads could spam users with file dialoges without them interacting with the page and e.g. have them unknowingly upload a file.
The issue with using an Observable is that, if it is asynchronous (i.e. when using the async
scheduler), you leave the user interaction context and the browser will not open the file dialog.
You can solve this only by making your Observable synchronous (which, actually, almost all preset Observables are). If you have e.g. a HTTP request, this won't be possible and you have to look for alternatives for opening the file dialog (though I'm not sure if any of those would work in your setup).
Here is an GitHub issue that is similiar to your problem with an explanation:
Therefore [due to the asynchronity], the click() call [...] is not triggered by a user-event, from Chrome's perspective, and consequently is ignored.
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
add a comment |
For security reasons, it is not possible in modern browsers to programatically invoke the click
event on a file input - UNLESS it happens during a user interaction. Otherwise, websites and ads could spam users with file dialoges without them interacting with the page and e.g. have them unknowingly upload a file.
The issue with using an Observable is that, if it is asynchronous (i.e. when using the async
scheduler), you leave the user interaction context and the browser will not open the file dialog.
You can solve this only by making your Observable synchronous (which, actually, almost all preset Observables are). If you have e.g. a HTTP request, this won't be possible and you have to look for alternatives for opening the file dialog (though I'm not sure if any of those would work in your setup).
Here is an GitHub issue that is similiar to your problem with an explanation:
Therefore [due to the asynchronity], the click() call [...] is not triggered by a user-event, from Chrome's perspective, and consequently is ignored.
For security reasons, it is not possible in modern browsers to programatically invoke the click
event on a file input - UNLESS it happens during a user interaction. Otherwise, websites and ads could spam users with file dialoges without them interacting with the page and e.g. have them unknowingly upload a file.
The issue with using an Observable is that, if it is asynchronous (i.e. when using the async
scheduler), you leave the user interaction context and the browser will not open the file dialog.
You can solve this only by making your Observable synchronous (which, actually, almost all preset Observables are). If you have e.g. a HTTP request, this won't be possible and you have to look for alternatives for opening the file dialog (though I'm not sure if any of those would work in your setup).
Here is an GitHub issue that is similiar to your problem with an explanation:
Therefore [due to the asynchronity], the click() call [...] is not triggered by a user-event, from Chrome's perspective, and consequently is ignored.
edited Nov 14 '18 at 18:41
answered Nov 14 '18 at 18:35
ggradnigggradnig
3,6431424
3,6431424
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
add a comment |
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
That I didn't know, thanks it was quite informative ! I guess I'll work around the app design in order for the file input call to be in the context of the clic event. Many thanks !
– Alexis Facques
Nov 14 '18 at 20:35
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305778%2ftriggering-a-click-on-a-child-components-file-input-wont-work-from-a-subscri%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
Can you reproduce the problem in a stackblitz?
– ConnorsFan
Nov 14 '18 at 17:33
Does it work if you do
setTimeout(()=>this.child.open(),0)
instead?– Aviad P.
Nov 14 '18 at 18:12
we need to see the service too so as @ConnorsFan said it would be nice to have a stackblitz
– Kevin ALBRECHT
Nov 14 '18 at 18:13
please paste the relevant content of
ParentService
– ggradnig
Nov 14 '18 at 18:24