working on a tool to work with google drive, and one operation requires that we have two file pickers and operate on the results. This is a "move" operation, so the first is to select the file to move, and the second is for the folder that the file should move to. I have both pickers defined like this:
btn_driveMove.on('click', (e) => {
console.log('btn_driveMove(): called.');
let tk = getLayeredStorage(currentUserEmail, 'access_token');
if(tk.indexOf('\\') !== -1) tk = tk.replace(/\\/g,'');
if(tk.indexOf('\"') !== -1) tk = tk.replace(/"/g, '');
gapi.client.setToken({access_token: tk});
gapi.load('picker', () => {
const selectFile = new google.picker.PickerBuilder()
.addView(new google.picker.DocsView().setSelectFolderEnabled(true))
.setOAuthToken(gapi.client.getToken().access_token)
.setCallback(fileSelectedCallback)
.build();
selectFile.setVisible(true);
});
});
function folderSelectedCallback(folderData, fileData) {
console.log('folderSelectedCallback(): called.');
console.log('File Data: ', fileData);
console.log('Folder Data: ', folderData);
const files = fileData.docs;
const folder = folderData.docs[0];
files.forEach(f => {
gapi.client.drive.files.update({
addParents: folder.id,
fileId: f.id,
removeParents: f.parentId
}).then(res => {
console.dir(res);
});
});
}
function fileSelectedCallback(fileData) {
console.log('FileSelectedCallback(): File Data: ', fileData);
const folderPicker = new google.picker.PickerBuilder()
.addView(new google.picker.DocsView()
.setIncludeFolders(true)
.setMimeTypes('application/vnd.google-apps.folder')
.setSelectFolderEnabled(true))
.setOAuthToken(gapi.client.getToken().access_token)
.setCallback((data) => folderSelectedCallback(data, fileData))
.build();
folderPicker.setVisible(true);
}
The issue is that sometimes the folder picker shows up on top of the file picker. The code still works correctly, but looks awful seeing two pickers pop up, close one, pick a file in the other, and the folder one comes back. Just isn't the way I want this presented....
The callback set in .setCallback()
is not called just once, but every time there's a change with the Picker. This is intended to allow a developer to setup specific actions for certain events in the Picker workflow.
The case in point, there is nothing that really needs to be done with the 'cancelled'
or 'loaded'
actions stored in data.action
. The real one we're interested in is 'picked'
. This means that the user has selected something in the Picker. (File, Folder, friendly alien, etc.)
We simply need to wrap the body of the callback handler with a simple if statement like this:
function pickerCallback(data){
if(data.action === 'picked'){
....... do some things ......
}
}
With this, the first callback should look like this, and ensures that the second picker does not show before the first has been used/disposed.
function fileSelectedCallback(fileData) {
console.log('FileSelectedCallback(): File Data: ', fileData);
if(fileData.action === 'picked'){
const folderPicker = new google.picker.PickerBuilder()
.addView(new google.picker.DocsView()
.setIncludeFolders(true)
.setMimeTypes('application/vnd.google-apps.folder')
.setSelectFolderEnabled(true))
.setOAuthToken(gapi.client.getToken().access_token)
.setCallback((data) => folderSelectedCallback(data, fileData))
.build();
folderPicker.setVisible(true);
}
}