Issue
Problem:
I am trying to execute a series of functions in a specific order. These functions all have asynchronous tasks inside of them; however, these functions need to happen sequentially.
The below code needs to do the following:
Delete current contents of Document Directory (this is because all files are persistent but I do NOT need them for permanent storage, only temporary)
Copy current file assets from their locations to the Document Directory
Zip up the folder of the Document Directory so I can store the zipped folder in AWS
Is it possible to ensure these functions wait for their asynchronous tasks to finish? (Some of these asynchronous tasks are run in a forEach loop -- this is not a single task within each function).
To take this a step further, can I execute the two (x2) copyFilesToDocumentDirectory() concurrently and still wait before executing zipDocumentDirectory()?
import React, { Component } from 'react';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
export default class AddMedia extends React.Component {
state = {
photoAssets: [],
videoAssets: [],
videoThumbnails: [],
thumbnailReady: false
};
zipDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
console.log("Zipped");
zip(path, path + "/urls.zip")
.then((path) => {
console.log("Zip complete");
})
.catch((err) => {
console.log(err);
});
};
deleteContentsOfDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
var data = RNFS.readDir(path)
.then((results) => {
results.forEach(result => {
/* I assume each item here is a FILE */
RNFS.unlink(result.path)
.then(() => {
console.log("File Deleted");
})
.catch((err) => {
console.log(err.message);
});
});
});
};
copyFilesToDocumentDirectory(assets) {
var path = RNFS.DocumentDirectoryPath;
assets.forEach(asset => {
RNFS.exists(asset.uri)
.then((status) => {
if(status) {
var newPath = path + "/" + asset.fileName;;
console.log("Copying from: ", asset.uri, " -- to: ", newPath);
RNFS.copyFile(asset.uri, newPath);
};
});
});
};
storeToAWS()
this.deleteContentsOfDocumentDirectory();
this.copyFilesToDocumentDirectory(this.state.photoAssets);
this.copyFilesToDocumentDirectory(this.state.videoAssets);
this.zipDocumentDirectory();
};
// ... Render code etc;
};
Efforts:
I wrote the above because that was the problem I am trying to solve. I thought this could be solved by Promises but I am relatively new to the idea of promises/async/await. I tried adding Promises to each method to wait for them to finish; however, the functions still ran synchronously and the asynchronous tasks ran after. The output is below the code showing the Zipped output inside zipDocumentDirectory() occurs BEFORE the asynchronous commands inside copyFilesToDocumentDirectory().
import React, { Component } from 'react';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
export default class AddMedia extends React.Component {
state = {
photoAssets: [],
videoAssets: [],
videoThumbnails: [],
thumbnailReady: false
};
zipDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
console.log("Zipped");
new Promise((resolve, reject) => {
zip(path, path + "/urls.zip")
.then((path) => {
console.log("Zip complete");
resolve();
})
.catch((err) => {
console.log(err);
reject();
});
});
};
deleteContentsOfDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
new Promise((resolve, reject) => {
var data = RNFS.readDir(path)
.then((results) => {
results.forEach(result => {
/* I assume each item here is a FILE */
RNFS.unlink(result.path)
.then(() => {
console.log("File Deleted");
resolve();
})
.catch((err) => {
console.log(err.message);
reject();
});
});
});
});
};
copyFilesToDocumentDirectory(assets) {
var path = RNFS.DocumentDirectoryPath;
assets.forEach(asset => {
new Promise((resolve, reject) => {
RNFS.exists(asset.uri)
.then((status) => {
if(status) {
var newPath = path + "/" + asset.fileName;;
console.log("Copying from: ", asset.uri, " -- to: ", newPath);
RNFS.copyFile(asset.uri, newPath);
resolve();
};
});
});
});
};
storeToAWS = async () => {
await this.deleteContentsOfDocumentDirectory();
await this.copyFilesToDocumentDirectory(this.state.photoAssets);
await this.copyFilesToDocumentDirectory(this.state.videoAssets);
// 2. Zip temporary folder storage (with encryption)
await this.zipDocumentDirectory();
OUTPUT:
LOG Zipped
LOG Copying from: XYZ/FEB964FB-3ABB-4CF7-A3B0-1E90BD1932C4.jpg -- to: XYZ/FEB964FB-3ABB-4CF7-A3B0-1E90BD1932C4.jpg
Solution
I added missing returns. I hope it will work now
import React, { Component } from 'react';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
export default class AddMedia extends React.Component {
state = {
photoAssets: [],
videoAssets: [],
videoThumbnails: [],
thumbnailReady: false
};
zipDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
console.log("Zipped");
return zip(path, path + "/urls.zip")
.then((path) => {
console.log("Zip complete");
})
.catch((err) => {
console.log(err);
reject();
});
};
deleteContentsOfDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
return RNFS.readDir(path)
.then((results) => {
return Promise.all(results.map(result => {
return RNFS.unlink(result.path)
.then(() => {
console.log("File Deleted");
})
.catch((err) => {
console.log(err.message);
});
}));
});
};
copyFilesToDocumentDirectory(assets) {
var path = RNFS.DocumentDirectoryPath;
return Promise.all(assets.map(asset => {
return RNFS.exists(asset.uri)
.then((status) => {
if(status) {
var newPath = path + "/" + asset.fileName;;
return RNFS.copyFile(asset.uri, newPath);
};
});
});
}));
};
storeToAWS = async () => {
await this.deleteContentsOfDocumentDirectory();
await this.copyFilesToDocumentDirectory(this.state.photoAssets);
await this.copyFilesToDocumentDirectory(this.state.videoAssets);
// 2. Zip temporary folder storage (with encryption)
await this.zipDocumentDirectory();
}
}
```
Answered By - Konrad Linkowski Answer Checked By - Katrina (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.