We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Filemanager - catch async provider request on success and failure

Hi,

I have a parent component containing a dropdown with different providers(ftp, filesystem etc) and a child component containing the syncfusion filemanager component.

When the user selects a provider from the list, a the ajaxsettings(see below number 2) gets setup to be sent by the syncfusion component. This gets sent to an Api, with some entry code based on your project https://github.com/SyncfusionExamples/ej2-aspcore-file-provider/blob/master/Controllers/FileManagerController.cs (see number 4 below)

Now the issue:

When the user selects from this dropdown, I want to block any still to be returned (ASYNC) requests by cathing this when it's coming back. Simple right? So I check if the current selection is equal to the provider returning.

But when trying to catch this in onsuccess()(see below number 3), if not current provider -> return. But the data still gets set after the event. How to catch/abort/prevent this?

(Seeking something similar to your Grid's beforeDataBound(). Or some other way.)


Im also seeking a solution for catching a failure popup using beforePopupOpen() for the issue above. If the request is failed, i don't need to see the error message.

The api returns the error as well as the providerinfo.

See code below number 4 for the code and number 1 for the class of the to be returned response.


angular side popup

 beforePopupOpen(args: BeforePopupOpenCloseEventArgs ) {

//args contains no visible data to any provider.

}

--------------------------------------1-------------------------------------------------------

public class FileManagerResponse

{

public string rootPath { get; set; }

public ProviderInfo providerInfo { get; set; }

public Token token { get; set; }

public FileManagerDirectoryContent CWD { get; set; }

public IEnumerable Files { get; set; }

public ErrorDetails Error { get; set; }

public FileDetails Details { get; set; }

}

public class ErrorDetails

{

public string Code { get; set; }

public string Message { get; set; }

public IEnumerable FileExists { get; set; }

}

-------------------------------------2--------------------------------------------------------

 beforeSend(args: BeforeSendEventArgs) {

 let providerInfo = this.selectedProvider;

let contentInfo: ContentInfo = { showFiles: this.fmOptions.browseType != BrowseType.SelectFolder, extensions: this.fmOptions.extensions, token: this.token };

const token = this.authService.getAccessToken();

if (args.ajaxSettings['url'] == null) {

args.cancel = true;

} else {

args.ajaxSettings['beforeSend'] = function (args2) {

//Setting authorization header

args2.httpRequest.setRequestHeader('access-control-allow-origin', '*');

args2.httpRequest.setRequestHeader("authorization", `Bearer ${token}`);

}

if (args.ajaxSettings['data']) {

let obj = JSON.parse(args.ajaxSettings['data']);

if (Array.isArray(obj)) {

obj.push({ providerInfo: JSON.stringify(providerInfo) });

obj.push({ contentInfo: JSON.stringify(contentInfo) });

} else {

obj.providerInfo = providerInfo;

obj.contentInfo = contentInfo;

}

args.ajaxSettings['data'] = JSON.stringify(obj);

}

}

}

-------------------------------------3--------------------------------------------------------

 onSuccess(args: SuccessEventArgs) {

 if ((args.result as FileManagerResponse).providerInfo.id === this.selectedProvider.id) { // dont proceed if another selection has been made.

this.rootPath = (args.result as FileManagerResponse).rootPath;

this.token = (args.result as FileManagerResponse).token;


if (!isEmpty(this.fmOptions.initial)) {

this.setInitialPath();

} else {

if (this.selectedFolder == "") {

this.selectedFolder = "\\";


if (this.fmOptions.browseType == BrowseType.SelectFolder) {

this.isValidSelected = true;

}


this.isValidSelectedChange.emit({ isValidSelected: this.isValidSelected });


if (this.sortingByDate) {

this.fileManager.sortBy = '_fm_modified';

this.fileManager.sortOrder = 'Descending';

}

}

}

} else {

return;

}

}

-----------------------------------------4----------------------------------------------------

using (var fileProvider = GetFileProvider(provider))

{

FileManagerResponse response = null;


switch (args.Action)

{

case "read":

// reads the file(s) or folder(s) from the given path.

response = fileProvider.GetFiles(args.Path, args.ContentInfo);

break;

case "delete":

// deletes the selected file(s) or folder(s) from the given path.

response = fileProvider.Delete(args.Path, args.Names);

break;

case "copy":

// copies the selected file(s) or folder(s) from a path and then pastes them into a given target path.

response = fileProvider.Copy(args.Path, args.TargetPath, args.Names, args.RenameFiles, args.TargetData);

break;

case "move":

// cuts the selected file(s) or folder(s) from a path and then pastes them into a given target path.

response = fileProvider.Move(args.Path, args.TargetPath, args.Names, args.RenameFiles, args.TargetData);

break;

case "details":

// gets the details of the selected file(s) or folder(s).

response = fileProvider.Details(args.Path, args.Names, args.Data);

break;

case "create":

// creates a new folder in a given path.

response = fileProvider.Create(args.Path, args.Name);

break;

case "search":

// gets the list of file(s) or folder(s) from a given path based on the searched key string.

response = fileProvider.Search(args.Path, args.SearchString, args.ContentInfo, false);

break;

case "rename":

// renames a file or folder.

response = fileProvider.Rename(args.Path, args.Name, args.NewName);

break;

default:

response = null;

break;

}

response.providerInfo = args.ProviderInfo;

return ToCamelCase(response);

}



---------------------------------------------------------------------------------------------

Package.json:

"@angular/cdk": "~13.1.1",

"@syncfusion/ej2-angular-filemanager": "20.1.60",



4 Replies

SA SureshRajan Alagarsamy Syncfusion Team March 7, 2023 04:18 PM UTC

Hi Laurens,


Query 1 : Regarding catching async provider requests on success in the Syncfusion File Manager component.


To prevent any event until it is completed, we suggest using the promise then() method and placing the required event or method inside this method. This will allow the next action only when the existing action gets completed. Refer to the below code snippet for further reference.


Code Snippet :


 

async onSuccess(args: SuccessEventArgs) {

  var promisenew Promise(function (resolve, reject) {   

    resolve('I promise to return this after 3 second!'); 

  });

  promise.then(() => {

    if ((args.result as FileManagerResponse).providerInfo.id === this.selectedProvider.id) {

      // dont proceed if another selection has been made.

      this.rootPath = (args.result as FileManagerResponse).rootPath;

      this.token = (args.result as FileManagerResponse).token;

    if (!isEmpty(this.fmOptions.initial)) {

      this.setInitialPath();

    } else {

      if (this.selectedFolder == "") {

      this.selectedFolder = "\\";

      if (this.fmOptions.browseType == BrowseType.SelectFolder) {

        this.isValidSelected = true;

    }

    this.isValidSelectedChange.emit({ isValidSelected: this.isValidSelected });

    if (this.sortingByDate) {

    this.fileManager.sortBy = '_fm_modified';

    this.fileManager.sortOrder = 'Descending';

    }

    }

  }

} else {

    return;

  }

   

}

}

 


Query 2 : To catch a failure message.


To catch a failure message, we suggest using the “Failure” event. You can achieve your requirement by customizing the Failure event arguments.


Check out the shared details and if we have misunderstood your query, please let us know and share your issue replicated sample. This will help us to validate the issue with more efficiency and provide a solution that meets your requirements.


Regards,
Suresh.



LA Laurens Albers March 8, 2023 03:20 PM UTC

Hi,


Query1

Thank you for your response, but that's not what i asked. I said previously:


"But when trying to catch this IN onSuccess(), 'if not current provider -> return'. But the data still gets set AFTER THE EVENT. How to catch/abort/prevent this?"

So when catching, returning or resolving(by using the promise in your example) the args in onsuccess(args: SuccessEventArgs), the condition stops the code, BUT soon right after this event, the data still get set into the filemanager.

thats why i also mentioned -> (Seeking something similar to your Grid's beforeDataBound(). Or some other way.)


Maybe some sort of component.ajaxcall.abort(). I need to stop the data from getting set to the component


You could do something as simple like:

onSuccess(args: SuccessEventArgs){

return null;

args.cancel=true;

}

Right after the onSuccess -> somewhere something still sets the data soon after this event.


Reproduce:

Select a provider "filesystem A" from dropdown > beforesend() gets triggered and fills the header etc, (see code previous comment) and the call gets made/sent by your syncfusion component (hidden somewhere) right after.

While that async call is being processed. Select provider "filesystem B" from dropdown > beforesend() gets triggered again and another call is made.

Now onSucces() finally gets triggered for the first time, but with the response from "filesystem B" > and sets the data shortafter.

After a short while "filesystem A" finally returns > onSucces() gets triggered again > and sets data shortafter, but (unwanted) OVERWRITES the current view and panel of 'filesystem B' which I am currently in.



More addtional context(if needed):

#fileManagerComponent

[height]="browserHeight"

[allowDragAndDrop]='fmOptions.allowedActions.dragDrop'

view='Details'

[ajaxSettings]='ajaxSettings'

[allowMultiSelection]='fmOptions.allowedActions.multiSelect'

[detailsViewSettings]='detailsViewSettings'

[navigationPaneSettings]='navigationPaneSettings'

[contextMenuSettings]='contextMenuSettings'

[toolbarSettings]="toolbarSettings"

[searchSettings]='searchSettings'

[enablePersistence]='false'

(beforeSend)='beforeSend($event)'

(fileSelect)='onFileSelect($event)'

(fileOpen)='onFileOpen($event)'

(success)='onSuccess($event)'

(menuOpen)='menuOpen($event)'

(beforePopupOpen)="beforePopupOpen($event)"

(menuClick)='menuClick($event)'

(created)='created($event)'>


Query 2

failure event can't stop the error from showing. That event comes after beforePopupOpen, unless i stop it there. The dialog is already visible when reaching the failure event.

So I use your beforePopupOpen(args) to catch/manage this. But there is no context within the event args to know from which provider call this is coming from. If I selected 3 different providers and 2 of them return a error after a while. I don't know which one belongs to who.

So I would like to know and prevent the ones from showing when the provider does not match the call. Which is somewhat related to the issue of Query 1.

As i mentioned before I am returning a providerId and more(which i added upon your exisitng .net code mentioned before) with the returning response.




LA Laurens Albers March 14, 2023 02:02 PM UTC

*Bump. Any luck on preventing the data from being set after onSuccess()



SA SureshRajan Alagarsamy Syncfusion Team March 17, 2023 04:38 PM UTC

Hi Laurens,


We have reviewed your query and shared code snippet. We understand that you are facing two concerns in File Manager component.


Query 1 : Based on your shared details and code snippet, we understand that you want to capture the File Manager response before rendering of the component. We have considered it as a feature at our end. Usually, Syncfusion will plan and implement the features based on feature rank, customer requested count, and volume wish list. We will implement and include this feature in any one of our upcoming releases.


The status of this feature can be tracked through our feedback portal below.


https://www.syncfusion.com/feedback/42183/new-event-before-datas-bound-to-the-file-manager-component


Query 2 : Need to remove the failure message and the current file information.


We suggest you to use the “Failure” event to remove the failure message using the SatusText argument. Also, you can get the file details from the file argument. Refer to the below code snippet for further reference.


Code Snippet :


[app.component.html]

 

<div class="sample-container">

       <ejs-filemanager id='overview' [ajaxSettings]='ajaxSettings' [view]='view' (failure)='failure($event)'>

        </ejs-filemanager>

</div>

 


[app.component.ts]

 

failure(args: any) {

  // you can remove the failure message

  args.error.statusText = '';

 

  // You can file details

  var fileInfo = args.error.file;

}

 


We have attached sample for your reference.


Sample : https://stackblitz.com/edit/angular-twteky-d6wgqc?file=src/app.component.ts


Check out the shared details and get back to us if you need any further assistance.


Regards,
Suresh.


Loader.
Live Chat Icon For mobile
Up arrow icon