Triggering a click() on a child component's file input won't work from a subscription












0















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...










share|improve this question


















  • 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
















0















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...










share|improve this question


















  • 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














0












0








0








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...










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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














  • 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








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












1 Answer
1






active

oldest

votes


















3














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.







share|improve this answer


























  • 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











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
});


}
});














draft saved

draft discarded


















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









3














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.







share|improve this answer


























  • 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
















3














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.







share|improve this answer


























  • 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














3












3








3







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.







share|improve this answer















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.








share|improve this answer














share|improve this answer



share|improve this answer








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



















  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python