Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 115 additions & 89 deletions docs/tasks/LargeFileUploadTask.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,142 @@
# Large File Upload Task - Uploading large files to OneDrive
# Large File Upload Task - Uploading large files to OneDrive, Outlook, Print API.

This task simplifies the implementation of OneDrive's [resumable upload](https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession).
References -
- [Outlook's large file attachment](https://docs.microsoft.com/en-us/graph/outlook-large-attachments)
- [OneDriveItem's resumable upload](https://docs.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0&preserve-view=true)
- [Print API's large file upload](https://docs.microsoft.com/en-us/graph/upload-data-to-upload-session)

## Creating the client instance

Refer [this documentation](../CreatingClientInstance.md) for initializing the client.

## Uploading from browser

HTML to select the file for uploading.

```HTML
<input id="fileUpload" type="file" onchange="fileUpload(this)" />
```

Get files from the input element and start uploading.
## Using the LargeFileUpload Task

#### Create an upload session
First step for any upload task is the creation of the upload session.
**Example of a payload for Outlook**
```typescript
async function fileUpload(elem) {
let file = elem.files[0];
try {
let response = await largeFileUpload(client, file, file.name);
console.log(response);
console.log("File Uploaded Successfully.!!");
} catch (error) {
console.error(error);
const payload = {
AttachmentItem: {
attachmentType: 'file',
name: "<FILE_NAMe>",
size: FILE_SIZE,
}
}
```
**Example of a payload for OneDrive**
```typescript
const payload = {
item: {
"@microsoft.graph.conflictBehavior": "rename",
name: "<FILE_NAMe>",
},
};
```
**Create the upload session**
```typescript
const uploadSession = LargeFileUploadTask.createUploadSession(client, "REQUEST_URL", payload)
```
#### Creating the LargeFileUploadTask object

async function largeFileUpload(client, file) {
try {
let options = {
path: "/Documents",
fileName: file.name,
rangeSize: 1024 * 1024,
};
const uploadTask = await MicrosoftGraph.OneDriveLargeFileUploadTask.create(client, file, options);
const response = await uploadTask.upload();
return response;
} catch (err) {
throw err;
}
* To create the LargeFileUploadTask object you need to create -
* An upload session as shown above.
* A `FileObject` instance.

**FileObject Interface**
```typescript
export interface FileObject {
content: any;
name: string;
size: number;
sliceFile(range: Range): Promise<ArrayBuffer | Blob | Buffer>;
}
```
The Microsoft Graph JavaScript Client SDK provides two implementions -
1. StreamUpload - Supports Node.js stream upload
```typescript

import StreamUpload from "@microsoft/microsoft-graph-client";
import * as fs from "fs";

const fileName = "<FILE_NAME>";
const stats = fs.statSync(`./test/sample_files/${fileName}`);
const totalsize = stats.size;
const readStream = fs.createReadStream(`./test/sample_files/${fileName}`);
const fileObject = new StreamUpload(readStream, fileName, totalsize);
```
Note - In case of a browser application, you can use [stream-browserify](https://www.npmjs.com/package/stream-browserify), [buffer](https://www.npmjs.com/package/buffer);

2. FileUpload - Supports upload of file formats - ArrayBuffer, Blob, Buffer
```typescript

import FileUpload from "@microsoft/microsoft-graph-client";
import * as fs from "fs";

const fileName = "<FILE_NAME>";
const stats = fs.statSync(`./test/sample_files/${fileName}`);
const totalsize = stats.size;
const readStream = fs.readFileSync(`./test/sample_files/${fileName}`);
const fileObject = new StreamUpload(readStream, fileName, totalsize);
```
***Note*** - You can also have a customized `FileObject` implementation which contains the `sliceFile(range: Range)` function which implements the logic to split the file into ranges.

**Initiate the LargefileUploadTask options with Progres Handler and Range Size**
```typescript
const progress = (range?: Range, extraCallBackParams?: unknown) => {
};
const completed = (result?: UploadResult, extraCallBackParams?: unknown) => {
};
const failure = (error?: GraphClientError, extraCallBackParams?: unknown) => {
};
const progressCallBack: Progress = {
progress,
completed,
failure,
extraCallBackParams, // additional parameters to the callback
};

const options: LargeFileUploadTaskOptions = {
rangeSize: 327680,
progressCallBack: progressCallBack,
};
```
**Create a LargefileUploadTask object**

## Uploading from NodeJS
```typescript
const uploadTask = new LargeFileUploadTask(client, fileObj, uploadSession, optionsWithProgress);
const uploadResult:UploadResult = await uploadTask.upload();
```
`UploadResult` contains the `location`(received in the Outlook API header response) and the `responseBody` properties.

## OneDriveLargeFileUploadTask.
You can also use `OneDriveLargeFileUploadTask` which provides easier access to upload to OneDrive API.
Example -
```typescript
function uploadFile() {
fs.readFile("<PATH_OF_THE_FILE>", {}, function(err, file) {
if (err) {
throw err;
}
let fileName = "<NAME_OF_THE_FILE_WITH_EXTN>";
oneDriveLargeFileUpload(client, file, fileName)
.then((response) => {
console.log(response);
console.log("File Uploaded Successfully.!!");
})
.catch((error) => {
throw err;
});
});
}
const progressCallBack: Progress = {
progress,
completed,
failure,
extraCallBackParams: true,
};

async function oneDriveLargeFileUpload(client, file, fileName) {
try {
let options = {
const options: OneDriveLargeFileUploadOptions = {
path: "/Documents",
fileName,
rangeSize: 1024 * 1024,
progressCallBack,
};
const uploadTask = await OneDriveLargeFileUploadTask.create(client, file, options);
const response = await uploadTask.upload();
return response;
} catch (err) {
console.log(err);
}
const readStream = fs.createReadStream(`./fileName`);
const fileObject = new StreamUpload(readStream, fileName, totalsize);
or
const readFile = fs.readFileSync(`./fileName`);
const fileObject = new FileUpload(readStream, fileName, totalsize);

const uploadTask = await OneDriveLargeFileUploadTask.createTaskWithFileObject(client, fileObject, options);
const uploadResult:UploadResult = await uploadTask.upload();
}
```
**Note - The `OneDriveLargeFileUploadTask.createTaskWithFileObject` also handles the upload session creation.**

## We can just resume the broken upload

Expand All @@ -98,38 +156,6 @@ let slicedFile = uploadTask.sliceFile(range);
uploadTask.uploadSlice(slicedFile, range, uploadTask.file.size);
```

## Uploading with custom options

_You can pass in the customized options using LargeFileUploadTask_

```typescript
async function largeFileUpload(client, file) {
const fileName = file.name;
const driveId = "<YOUR_DRIVE_ID>";
const path = "<LOCATION_TO_STORE_FILE>";
try {
const requestUrl = `/drives/${driveId}/root:${path}/${fileName}:/createUploadSession`;
const payload = {
item: {
"@microsoft.graph.conflictBehavior": "fail",
name: fileName,
},
};
const fileObject = {
size: file.size,
content: file,
name: fileName,
};
const uploadSession = await LargeFileUploadTask.createUploadSession(client, requestUrl, payload);
const uploadTask = await new LargeFileUploadTask(client, fileObject, uploadSession);
const response = await uploadTask.upload();
return response;
} catch (err) {
throw err;
}
}
```

## Cancelling a largeFileUpload task

_Cancelling an upload session sends a DELETE request to the upload session URL_
Expand Down
Loading