Rendering Flat JSON Data in the EJ2 TypeScript File Manager Control
22 Jun 202424 minutes to read
The File Manager uses a flat data object as an array of JavaScript objects for rendering, eliminating the need to define ajaxSettings url. To load a folder data as an array of JavaScript objects, use the File Manager component’s fileSystemData property with a type of fileData interface. This means you no longer need to use a separate service provider, as you can integrate services like Google, Amazon, Azure, and others directly into your JavaScript code using the FileManager’s action events. For example, you can integrate Google Drive by following the Google Drive API Quickstart guide for JavaScript.
Event Information
Event Name | Description | ||
---|---|---|---|
beforeDelete | This event is triggered before the deletion of a file or folder occurs. It can be utilized to prevent the deletion of specific files or folders. Any actions, such as displaying a spinner for deletion, can be implemented here. | ||
delete | DeleteEventArgs | path, itemData, cancel. | This event is triggered after the file or folder is deleted successfully. The deleted file or folder details can be retrieved here. Additionally, custom elements’ visibility can be managed here based on the application’s use case. |
beforeFolderCreate | This event is triggered before a folder is created. It allows for the restriction of folder creation based on the application’s use case. | ||
folderCreate | This event is triggered when a folder is successfully created. It provides an opportunity to retrieve details about the newly created folder. | ||
search | This event is triggered when a search action occurs in the search bar of the File Manager component. It triggers each character entered in the input during the search process. | ||
beforeRename | This event is triggered when a file or folder is about to be renamed. It allows for the restriction of the rename action for specific folders or files by utilizing the cancel option. | ||
rename | This event is triggered when a file or folder is successfully renamed. It provides an opportunity to fetch details about the renamed file. | ||
beforeMove | This event is triggered when a file or folder begins to move from its current path through a copy/cut and paste action. | ||
move | This event is triggered when a file or folder is pasted into the destination path. |
Local data
The FileManager can be populated with local data that contains the array of fileData
interface objects with parentId
mapping.
To render the root-level folder, specify the parentId
as null, or there is no need to specify the parentId
in the array of fileData
interface objects.
import { FileManager, Toolbar, NavigationPane, DetailsView, ContextMenu, Permission, FileData} from '@syncfusion/ej2-filemanager';
FileManager.Inject(Toolbar, NavigationPane, DetailsView, ContextMenu);
/**
* File Manager flat data sample
*/
let resultData: FileData[] = [
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T18:16:38.4384894+05:30"),
filterPath: "",
hasChild: true,
id: '0',
isFile: false,
name: "Files",
parentId: null,
size: 1779448,
type: "folder"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\",
hasChild: false,
id: '1',
isFile: false,
name: "Archives",
parentId: '0',
size: 680786,
type: "folder"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\",
hasChild: false,
id: "2",
isFile: false,
name: "Audio",
parentId: "0",
size: 20,
type: "folder"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\",
hasChild: false,
id: "3",
isFile: false,
name: "Video",
parentId: "0",
size: 6172,
type: "folder"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Archives\\",
hasChild: false,
id: "4",
isFile: true,
name: "EJ2_File_Manager",
parentId: "1",
size: 12403,
type: ".docx"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Archives\\",
hasChild: false,
id: "5",
isFile: true,
name: "EJ2_File_Manager",
parentId: "1",
size: 90099,
type: ".pdf"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Archives\\",
hasChild: false,
id: "6",
isFile: true,
name: "File_Manager_PPT",
parentId: "1",
size: 578010,
type: ".pptx"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Archives\\",
hasChild: false,
id: "7",
isFile: true,
name: "File_Manager",
parentId: "1",
size: 274,
type: ".txt"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Audio\\",
hasChild: false,
id: "8",
isFile: true,
name: "Music",
parentId: "2",
size: 10,
type: ".mp3"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Audio\\",
hasChild: false,
id: "9",
isFile: true,
name: "Sample_Music",
parentId: "2",
size: 10,
type: ".mp3"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Video\\",
hasChild: false,
id: "10",
isFile: true,
name: "Demo_Video",
parentId: "3",
size: 10,
type: ".mp4"
},
{
dateCreated: new Date("2023-11-15T19:02:02.3419426+05:30"),
dateModified: new Date("2024-01-08T16:55:20.9464164+05:30"),
filterPath: "\\Video\\",
hasChild: false,
id: "11",
isFile: true,
name: "Sample_Video",
parentId: "3",
size: 10,
type: ".mp4"
}
];
let fileObject: FileManager = new FileManager({
fileSystemData: [].slice.call(resultData) as { [key: string]: Object }[],
toolbarSettings: { items: ['NewFolder', 'Cut', 'Copy', 'Paste', 'Delete', 'Rename', 'SortBy', 'Refresh', 'Selection', 'View', 'Details'], visible: true },
contextMenuSettings: { file: ["Cut", "Copy", "Paste", "Delete", "Rename", "|", "Details"], folder: ["Open", "|", "Cut", "Copy", "Paste", "|", "Delete", "Rename", "|", "Details"], layout: ["SortBy", "View", "Refresh", "|", "Paste", "|", "NewFolder", "|", "Details", "|", "SelectAll"], visible: true }
});
fileObject.appendTo('#filemanager');
<!DOCTYPE html>
<html lang="en">
<head>
<title>Essential JS 2 File Manager</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 File Manager Component" />
<meta name="author" content="Syncfusion" />
<link href="index.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-grids/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-filemanager/styles/material.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='loader'>Loading....</div>
<div id="container">
<div id="filemanager"></div>
</div>
</body>
</html>
Rendering Flat JSON Data from Google service
In the following topic, we can learn about reading files from Google API using the File Manager’s action events. This eliminates the need to define ajaxSettings url.
These events enable you to access essential item details from the event argument. To perform file operation corresponding to your service, use the cancel
property in File Manager’s action event and customize the fileSystemData based on your current service data.
The example retrieves the google drive file details as Flat data object and handle the read response from source by updating fileSystemData
property with retrieved data.
To set up File Manager component with google service, create a client ID and API key for your google account. To learn more about generating the client credentials from the from Google API Console, refer to this link.
async function fetchData() {
// Load the Drive API client library
await gapi.client.load('drive', 'v3');
let nextPageToken = null;
let allFiles = [];
do {
const response = await gapi.client.drive.files.list({
pageSize: 1000,
fields: 'nextPageToken, files(id, name, mimeType, size, parents, thumbnailLink, trashed)',
pageToken: nextPageToken,
q: 'trashed=false'
});
allFiles = allFiles.concat(response.result.files);
nextPageToken = response.result.nextPageToken;
} while (nextPageToken);
const files = allFiles;
// Create a flat array representing parent-child relationships for File Manager fileSystemData property
window.fileSystemData = await createFlatData(files);
}
async function createFlatData(files) {
...
await Promise.all(files.map(async file => {
isFileOrFolder = file.mimeType == 'application/vnd.google-apps.folder' ? false : true;
if (!isFileOrFolder) {
hasSubitems = file.name == 'Files'? true : doesFolderHaveSubfolders(fileList, file.id);
}
var fileType = getFileTypeFromName(file.name);
var imageUrl = file.thumbnailLink;
//Frame File Manager response data by retrieveing the folder details from google service.
if (file.name == 'Files') {
rootId = file.id;
fileDetails = {
id: '0',
name: file.name,
parentId: null,
isFile: file.mimeType == 'application/vnd.google-apps.folder'? false : true,
hasChild: hasSubitems,
size: file.size == undefined? '0' : file.size,
filterPath: '',
originalID: file.id
};
} else {
fileDetails = {
id: file.id,
name: file.name,
isFile: file.mimeType == 'application/vnd.google-apps.folder' ? false : true,
hasChild: hasSubitems,
size: file.size == undefined? '0' : file.size,
filterPath: file.filterPath,
imageUrl: imageUrl,
originalID: file.id
};
}
if (file.parents) {
file.parents.forEach(async parentId => {
parentDetails = {
id: fileDetails.id,
name: fileDetails.name,
parentId: fileDetails.name == "Files" ? null : parentId,
isFile: fileDetails.isFile,
type: fileDetails.isFile ? fileType : "",
hasChild: fileDetails.hasChild,
size: fileDetails.size,
filterPath: fileDetails.name == "Files" ? "" : fileDetails.filterPath,
imageUrl: fileDetails.imageUrl,
originalID: fileDetails.originalID
};
await flatData.push(parentDetails);
flatData.sort((a, b) => a.name.localeCompare(b.name));
});
} else {
// If a file has no parents, it is a root-level item
await flatData.push(fileDetails);
}
}));
...
// Return flat array representing parent-child relationships from Google Drive
return await(newData);
}
Delete action
To enable the delete operation in the File Manager component with Google services, you can use the beforeDelete event. By setting the cancel
property to true
in the beforeDelete
event, you can prevent the default delete action of the File Manager component. Then, you can make a Google API request with the help of event argument to delete the file from Google Drive. Additionally, to update the fileSystemData
property with the current Google Drive data, you can call the fetchData
method in the gapi
success callback. This ensures that the File Manager component remains synchronized with the Google Drive data during the delete operation.
Here is an example of how you can handle the delete operation using the beforeDelete
event:
beforeDelete: function deleting(args) {
// Cancel the default delete action
args.cancel = true;
// Create a new Drive API request to delete the file or folder
args.itemData.forEach(function(item) {
gapi.client.drive.files.delete({
fileId: item.originalID,
}).then(function(response) {
// Success: load the updated Google Drive data within File Manager component.
fetchData();
}, function(error) {
console.error('Error deleting folder:', error);
});
});
},
Copy action
To enable the copy operation in the File Manager component with Google services, you can use the beforeMove event. The isCopy
property in the event argument in true
for copy operation. By setting the cancel
property to true
in the beforeMove
event, you can prevent the default copy action of the File Manager component. Then, you can make a Google API request with the help of event argument to copy the file from Google Drive. Additionally, to update the fileSystemData
property with the current Google Drive data, you can call the fetchData
method in the gapi
success callback. This ensures that the File Manager component remains synchronized with the Google Drive data during the copy operation.
Here is an example of how you can handle the copy operation using the beforeMove
event:
beforeMove: function moving(args) {
// Cancel the default move action
args.cancel = true;
// Check if the operation is a copy or a cut
if(args.isCopy) {
// Update the parents property to move the file to the new folder
var newParentFolderId = args.targetData.originalID;
// Perform copy operation.
args.itemData.forEach(async function(item) {
var originalFolderId = item.originalID;
// Check if the item is a folder or a file
if(item.type == "") {
// Get information about the original folder
gapi.client.drive.files.get({
fileId: originalFolderId,
fields: 'id,name,parents,kind,mimeType'
}).then(function(response) {
var folderMetadata = response.result;
// Create a new folder in the destination
gapi.client.drive.files.create({
resource: {
name: folderMetadata.name,
mimeType: folderMetadata.mimeType,
parents: [newParentFolderId]
}
}).then(function(newFolder) {
// Get the contents of the original folder
gapi.client.drive.files.list({
q: "'" + originalFolderId + "' in parents",
fields: 'files(id,name,kind,mimeType)',
pageSize: 1000
}).then(function(contentsResponse) {
var contents = contentsResponse.result.files;
// Iterate through the contents and copy each file or subfolder
contents.forEach(function(item) {
if (item.kind === 'drive#folder') {
// Recursively copy subfolders
copyFolder(item.id, newFolder.result.id);
} else {
// Copy files
gapi.client.drive.files.copy({
fileId: item.id,
resource: {
name: item.name,
parents: [newFolder.result.id]
}
}).then(function(copiedFile) {
// Update the copied file's properties if needed
var updatedProperties = {
// Add any additional properties you want to update
};
gapi.client.drive.files.update({
fileId: copiedFile.result.id,
resource: updatedProperties
}).then(function(updatedFile) {
// Success: load the copied Google Drive folder data within File Manager component.
fetchData();
...
return;
}
...
// Function to copy a folder and its contents
async function copyFolder(originalFolderId, newParentFolderId) {
// Get information about the original folder
await gapi.client.drive.files.get({
fileId: originalFolderId,
fields: 'id,name,parents,kind,mimeType'
}).then(async function(response) {
var folderMetadata = response.result;
// Create a new folder in the destination
await gapi.client.drive.files.create({
resource: {
name: folderMetadata.name,
mimeType: folderMetadata.mimeType,
parents: [newParentFolderId]
}
}).then(async function(newFolder) {
// Get the contents of the original folder
await gapi.client.drive.files.list({
q: "'" + originalFolderId + "' in parents",
fields: 'files(id,name,kind,mimeType)',
pageSize: 1000
}).then(async function(contentsResponse) {
var contents = contentsResponse.result.files;
// Iterate through the contents and copy each file or subfolder
contents.forEach(async function(item) {
if (item.kind === 'drive#folder') {
// Recursively copy subfolders
copyFolder(item.id, newFolder.result.id);
} else {
// Copy files
await gapi.client.drive.files.copy({
fileId: item.id,
resource: {
name: item.name,
parents: [newFolder.result.id]
}
}).then(async function(copiedFile) {
// Update the copied file's properties if needed
var updatedProperties = {
// Add any additional properties you want to update
};
await gapi.client.drive.files.update({
fileId: copiedFile.result.id,
resource: updatedProperties
}).then(function(updatedFile) {
}).catch(function(error) {
console.error('Error updating copied file:', error);
});
}).catch(function(error) {
console.error('Error copying file:', error);
});
}
});
...
Move action
To enable the move operation in the File Manager component with Google services, you can use the beforeMove event. The isCopy
property in the event argument in false
for move operation. By setting the cancel
property to true
in the beforeMove
event, you can prevent the default move action of the File Manager component. Then, you can make a Google API request with the help of event argument to move the file from Google Drive. Additionally, to update the fileSystemData
property with the current Google Drive data, you can call the fetchData
method in the gapi
success callback. This ensures that the File Manager component remains synchronized with the Google Drive data during the move operation.
Here is an example of how you can handle the move operation using the beforeMove
event:
beforeMove: function moving(args) {
// Cancel the default move action
args.cancel = true;
...
//Perform cut operation.
args.itemData.forEach(function(item) {
// Get information about the original file
gapi.client.drive.files.get({
fileId: item.originalID,
fields: 'id,parents', // Add any other fields you might need
}).then(function(response) {
var fileMetadata = response.result;
// Update the parents property to move the file to the new folder
var newParentFolderId = [args.targetData.originalID];
// Send the update request
gapi.client.drive.files.update({
fileId: item.originalID,
addParents: newParentFolderId,
removeParents: fileMetadata.parents[0],
}).then(function(updatedFile) {
// Success: load the Google Drive moved file data within File Manager component.
fetchData();
}, function(error) {
console.error('Error moving file:', error);
});
}, function(error) {
console.error('Error retrieving file metadata:', error);
});
});
},
Folder create action
To enable the folder create operation in the File Manager component with Google services, you can use the beforeFolderCreate event. By setting the cancel
property to true
in the beforeFolderCreate
event, you can prevent the default folder create action of the File Manager component. Then, you can make a Google API request with the help of event argument to create folder to Google Drive. Additionally, to update the fileSystemData
property with the current Google Drive data, you can call the fetchData
method in the gapi
success callback. This ensures that the File Manager component remains synchronized with the Google Drive data during the folder creation operation.
Here is an example of how you can handle the folder creation operation using the beforeFolderCreate
event:
beforeFolderCreate: function onCreate(args) {
// Cancel the default folder creation action
args.cancel = true;
// Create a new Drive API request to create a folder
var body = {
'name': args.folderName,
'mimeType': "application/vnd.google-apps.folder",
'parents': [args.parentFolder[0].originalID]
};
var request = gapi.client.drive.files.create({
'resource': body
});
request.execute(function(resp) {
if (resp.error) {
console.error('Error:', resp.error.message);
} else {
// success: load the newly created Google Drive data within File Manager component.
fetchData();
}
});
},
Rename action
To enable the rename operation in the File Manager component with Google services, you can use the beforeRename event. By setting the cancel
property to true
in the beforeRename
event, you can prevent the default rename action of the File Manager component. Then, you can make a Google API request with the help of event argument to rename the file from Google Drive. Additionally, to update the fileSystemData
property with the current Google Drive data, you can call the fetchData
method in the gapi
success callback. This ensures that the File Manager component remains synchronized with the Google Drive data during the rename operation.
Here is an example of how you can handle the rename operation using the beforeRename
event:
beforeRename: function rename(args) {
// Cancel the default rename action
args.cancel = true;
// Create a new Drive API request to find the file or folder name
gapi.client.drive.files.list({
q: "name = '" + args.itemData[0].name + "'",
fields: 'files(id,name,parents)', // Add any other fields you might need
}).then(function(response) {
var files = response.result.files;
if (files && files.length > 0) {
// The first file in the list is the one you're looking for
var foundFile = files[0];
var metadata = {
name: args.newName,
};
// Create a new Drive API request to rename the file or folder name
gapi.client.drive.files.update({
fileId: foundFile.id,
resource: metadata,
}).then(function(updatedFile) {
// Success: load the renamed Google Drive data within File Manager component.
fetchData();
}, function(error) {
console.error('Error updating file:', error);
});
}
}, function(error) {
console.error('Error retrieving file metadata:', error);
});
},
Upload action
To enable the upload operation in the File Manager component with Google services, you can use the uploadListCreate event. This event provides access to details of the file selected in the browser, including metadata such as the file name
, size
, and content type
. Using the event argument, you can make a Google API request to upload the file to Google Drive. Additionally, to update the fileSystemData
property with the current Google Drive data, you can call the fetchData
method in the gapi
success callback. This ensures that the File Manager component remains synchronized with the Google Drive data during the upload operation.
Here is an example of how you can handle the upload operation using the uploadListCreate
event:
uploadListCreate: async function uploadFile(args) {
var fileObj = document.getElementById("file").ej2_instances[0];
var pathArray = fileObj.pathNames;
var folderName = pathArray[pathArray.length -1 ];
var parentFolderId = fileObj.fileSystemData.filter(function(obj) { return obj.name == folderName; })[0].originalID;
var folders = args.fileInfo.name.split('/');
var fileName = folders.length > 1 ? folders[folders.length - 1] : args.fileInfo.name;
const file = args.fileInfo.rawFile;
// Create a new Drive API request to upload a file
var body = {
'name': fileName,
'mimeType': args.fileInfo.type,
'parents': [parentFolderId]
};
var request = gapi.client.drive.files.create({
'resource': body
});
request.execute(function(resp) {
if (resp.error) {
console.error('Error:', resp.error.message);
args.element.getElementsByClassName("e-file-status")[0].innerText = "Upload Failed";
args.element.getElementsByClassName("e-file-status")[0].classList.add("e-upload-fails");
} else {
// Success: load the uploaded data within File Manager component.
args.element.getElementsByClassName("e-file-status")[0].innerText = "Upload successful";
args.element.getElementsByClassName("e-file-status")[0].classList.add("e-upload-success");
// Success: load the updated Google Drive data within File Manager component.
fetchData();
}
});
},
Download action
To enable the Download operatipon in the File Manager component with Google services, you can use the beforeDownload event. This event provides access to details of the file selected in the File Manager. By setting the cancel
property to true
in the beforeDownload
event, you can prevent the default delete action of the File Manager component. Then, you can make a Google API request with the help of event argument to Download the raw file from Google Drive.
beforeDownload: function beforeDownload(args) {
// Cancel the default download action
args.cancel = true;
var fileData = args.data.data;
const zip = new JSZip();
//To download multiple files as zip folder.
if(fileData.length > 1 || !fileData[0].isFile) {
downloadFiles(fileData);
}
//To download single file.
else {
// Fetch the file content using the Google Drive API
fetch(`https://www.googleapis.com/drive/v3/files/${fileData[0].id}?alt=media`, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + gapi.auth.getToken().access_token,
},
})
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
return response.blob();
})
.then(function(blob) {
// Display image preview
var img = document.createElement('img');
img.src = URL.createObjectURL(blob);
img.alt = fileData[0].name; // Set alternative text
document.body.appendChild(img);
// Create a download link
var downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = fileData[0].name; // Set the desired file name
document.body.appendChild(downloadLink);
downloadLink.click();
// Remove the link and image from the document
document.body.removeChild(downloadLink);
document.body.removeChild(img);
})
.catch(function(error) {
console.error('Error downloading file:', error);
});
}
},
...
function downloadFiles(files) {
const zip = new JSZip();
const totalCount = files.some(file => file.type === "") ? getTotalFileCount(files) : files.length;
const name = files.some(file => file.type == "") ? 'folders' : 'files';
// Iterate through files and add them to the zip
files.forEach(file => {
if (file.type === '') {
// If it's a folder, recursively fetch its contents
fetchFolderContents(file.id).then(response => {
downloadFiles(response.result.files);
});
} else {
// If it's a file, download and add it to the zip
fetch(`https://www.googleapis.com/drive/v3/files/${file.id}?alt=media`, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + gapi.auth.getToken().access_token,
},
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
return response.blob();
})
.then(blob => {
// Add file content to the zip
zip.file(file.name, blob);
// Check if all files are added, then create the zip
if (Object.keys(zip.files).length === totalCount) {
zip.generateAsync({ type: 'blob' }).then(zipBlob => {
// Trigger download
const a = document.createElement('a');
a.href = URL.createObjectURL(zipBlob);
a.download = name + '.zip';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
})
.catch(error => {
console.error('Error downloading file:', error);
});
}
});
}
Get image action
To enable the image preview in the File Manager component with Google services, you can use the File Manager fileSystemData property response with imageUrl
field.
In the example, the File Manager retrieves the Google Drive file details as flat data and update the imageUrl field with Google Drive’s file thumbnailLink
at initial render.
async function createFlatData(files) {
...
await Promise.all(files.map(async file => {
...
var imageUrl = file.thumbnailLink;
//Frame File Manager response data by retrieveing the folder details from google service.
if (file.name == 'Files') {
rootId = file.id;
fileDetails = {
id: '0',
name: file.name,
parentId: null,
isFile: file.mimeType == 'application/vnd.google-apps.folder'? false : true,
hasChild: hasSubitems,
size: file.size == undefined? '0' : file.size,
filterPath: '',
originalID: file.id
};
} else {
fileDetails = {
id: file.id,
name: file.name,
isFile: file.mimeType == 'application/vnd.google-apps.folder' ? false : true,
hasChild: hasSubitems,
size: file.size == undefined? '0' : file.size,
filterPath: file.filterPath,
imageUrl: imageUrl,
originalID: file.id
};
}
...
Note: For a complete example on handling Google Drive file details as flat data in the File Manager component, view the example on GitHub.