# FileChooser::launchAsync does nothing

**URL:** <https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507>\
**Category:** General JUCE discussion\
**Created:** [August 23, 2021, 1:51pm UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507 "2021-08-23T13:51:46Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![pajczur](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pajczur](https://forum.juce.com/u/pajczur)\
**Post date:** [August 23, 2021, 1:51pm UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/1 "2021-08-23T13:51:46Z")

</div>

Hello,  
in my plugins I was always using `FileChooser::browseForFileToOpen()` to open files.

But after last update of JUCE and Projucer I can’t do that.  
It looks like macro `JUCE_MODAL_LOOPS_PERMITTED` is set to false, so `browseForFileToOpen()` is not even declared in that case.

I’ve read ([link](https://forum.juce.com/t/compile-error-with-juce-modal-loops-permitted-0/44269/2) to post) that I should now use `launchAsync()`.

But actually it doesn’t work for me. When I call `launchAsync()` there is no action. Just nothing happens, no window is opened. I have no idea what I do wrong.

My code looks like that:

```auto
String defaultPath = File::getSpecialLocation(File::SpecialLocationType::userApplicationDataDirectory).getFullPathName();
File defaultDirectory = File(defaultPath );

std::unique_ptr<FileChooser> fChooser;
fChooser = std::make_unique<FileChooser>("Choose file", defaultDirectory, "*.txt", true, false, this);

auto folderChooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;

fChooser->launchAsync(folderChooserFlags, [this](const FileChooser& chooser)
{
    File chosenFile = chooser.getResult();
    // here is my code to handle chosen files data
});

```

I also tried other variations of `folderChooserFlags`, and nothing happens, but in one case I get runtime error, when my flags looked like that:  
`int folderChooserFlags = juce::FileBrowserComponent::canSelectFiles | juce::FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;`

then I got error:  
Exception thrown: read access violation.  
in the `functional` file in line:  
`return (_Mystorage._Ptrs[_Small_object_num_ptrs - 1]);`

Please help me.

For any advice great thanks in advance.

---

<div class="post-metadata">

**Author:** ![PierreGuillot](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pierreguillot/32/11653_2.png) [@PierreGuillot](https://forum.juce.com/u/PierreGuillot)\
**Post date:** [August 23, 2021, 2:28pm UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/2 "2021-08-23T14:28:57Z")

</div>

It seems that the `FileChooser` is deleted before it gets launched. I suggest you store the unique pointer of the `FileChooser` in your class and then do `myFileChooser = std::make_unique<FileChooser>(...)`. Look at the example in the documentation of the class.

---

<div class="post-metadata">

**Author:** ![pajczur](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pajczur](https://forum.juce.com/u/pajczur)\
**Post date:** [August 25, 2021, 10:20am UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/3 "2021-08-25T10:20:42Z")

</div>

Hello,  
great thanks. You are right. Your advice helped.

But now I have two more issues 🙂 :  
But now I wonder how to properly capture if user clicked “cancel”.

I know that if user click “cancel” then `FileChooser::getResult()` gives me `nullptr`.  
But I am not sure if it’s enough to be sure that user clicked “cancel”. I can imagine situation, that user didn’t click “cancel”, but `getResult()` can still return `nullptr`. Am I right? For example if user choose some strange file or file which was deleted before click “open” or anything else. Am I right?

So how to be sure that user clicked “cancel”?

And the second issue is about deleting object pointed by `std::unique_ptr<FileChooser> fChooser;`:  
I need to use `FileChooser` in many various scenarios. Not only for opening file, but also for example for “save as…”. So I need different comunicate.  
So now I should call:  
`std::make_unique<FileChooser>("Save as...", fPresetsDirectory, "*.txt", true, false, this);`  
instead:  
`std::make_unique<FileChooser>("Choose preset", fPresetsDirectory, "*.txt", true, false, this);`

So I wonder if I can use for that the same object:  
`std::unique_ptr<FileChooser> fChooser;`

I understand I can do that but before I use `std::make_unique<FileChooser>` first I should call:  
`fChooser.reset();`

Am I right?  
Or is there any better solution?

And is it good idea to call `fChooser.reset();` every time on the end of lambda like:

```auto
fChooser->launchAsync(folderChooserFlags, [this](const FileChooser& chooser)
{
    File chosenFile = chooser.getResult();
    // here is my code to handle chosen files data
    `fChooser.reset();`
});

```

Is it good idea?

For any help great thanks in advance.

Best Regards

---

<div class="post-metadata">

**Author:** ![PierreGuillot](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pierreguillot/32/11653_2.png) [@PierreGuillot](https://forum.juce.com/u/PierreGuillot)\
**Post date:** [August 25, 2021, 11:33am UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/4 "2021-08-25T11:33:54Z")

</div>

If the user clicks **cancel** , `getResult()` returns an empty `juce::File` (the path has an empty string) but if you prefer you can also use `getResults()` (with an _s_) and if the array is empty, it means that the user clicked **cancel** and nothing has been selected.

`fChooser` is a `unique_ptr<>` so each time you do `fChooser = std::make_unique<FileChooser>(...)`, it deleted the previous pointer stored in `fChooser` and replaces it with the new one (so there is no need of `fChooser.reset()`). Of course, you can use the same `unique_ptr<>` (and if fact most of the time, you should), it ensures that only one `FileChooser` is displayed at a time.

---

<div class="post-metadata">

**Author:** ![pajczur](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pajczur](https://forum.juce.com/u/pajczur)\
**Post date:** [August 25, 2021, 3:29pm UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/5 "2021-08-25T15:29:40Z")

</div>

> [@PierreGuillot](#):
>
> Of course, you can use the same `unique_ptr<>` (and if fact most of the time, you should), it ensures that only one `FileChooser` is displayed at a time.

That’s right. I would like to use the same `unique_ptr<FileChooser>`, but to do that first I need to be able to change “dialogBoxTitle”, which is normally set only in `FileChooser` constructor. So to have new “dialogBoxTitle” I need to create new `unique_ptr<FileChooser>`.  
I can’t find the solution how to change the “dialogBoxTitle” in existing `FileChooser` object

---

<div class="post-metadata">

**Author:** ![PierreGuillot](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pierreguillot/32/11653_2.png) [@PierreGuillot](https://forum.juce.com/u/PierreGuillot)\
**Post date:** [August 26, 2021, 7:10am UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/6 "2021-08-26T07:10:18Z")

</div>

Yes, each time you want to change the title, the file patterns, etc. you have to create a new instance. Why would you like to change the title of an existing instance?

---

<div class="post-metadata">

**Author:** ![pajczur](https://avatars.discourse-cdn.com/v4/letter/p/e9a140/32.png) [@pajczur](https://forum.juce.com/u/pajczur)\
**Post date:** [August 26, 2021, 11:29am UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/7 "2021-08-26T11:29:30Z")

</div>

> Why would you like to change the title of an existing instance?  
> As you suggested before to use the same `unique_ptr<>` I thought you meant the same object pointed by `unique_ptr<>`. So to do that I need various “dialogBoxTitle” for various type of window.

But if you meant just the same `unique_ptr<>` (not object pointed by) so then everything make sense for me.

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![stephenk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/stephenk/32/15198_2.png) [@stephenk](https://forum.juce.com/u/stephenk)\
**Post date:** [September 8, 2021, 4:24pm UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/8 "2021-09-08T16:24:34Z")

</div>

> [@PierreGuillot](#):
>
> If the user clicks **cancel** , `getResult()` returns an empty `juce::File` (the path has an empty string)

So what would be the correct way to test for cancelled in this case? File::exists()?

```auto
        File myFile (chooser.getResult());
        
        if (myFile.exists())
            DBG("GOOD!" + myFile.getFullPathName());
        else
            DBG("CANCELLED!");

```

---

<div class="post-metadata">

**Author:** ![connorreviere](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/connorreviere/32/4890_2.png) [@connorreviere](https://forum.juce.com/u/connorreviere)\
**Post date:** [September 8, 2021, 4:57pm UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/9 "2021-09-08T16:57:24Z")

</div>

`File::exists()` returns false immediately if the path string is empty, so it seems like the best choice for detecting cancellation for single file selections IMO. I like the approach of calling `FileChooser::getResults()` and checking its size for multi-file selections.

It would be nice to have to some explicit indicator that the user cancelled the selection, though. The old modal `FileChooser::browseFor*` functions returned a `bool` for this purpose, but there’s no equivalent when using `FileChooser::launchAsync`.

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [November 17, 2021, 8:26am UTC](https://forum.juce.com/t/filechooser-launchasync-does-nothing/47507/10 "2021-11-17T08:26:41Z")

</div>

> [@connorreviere](#):
>
> It would be nice to have to some explicit indicator that the user cancelled the selection

I’m using this to check if it’s cancelled:

```auto
if (myFile == File())
    // cancelled`

```
