Files

So far we’ve covered how to save JavaScript objects in the platform. But the platform supports saving (and retrieving) files too. This functionality isn’t intended to replace a CDN or static asset repository but it can serve as a dynamic asset repository.

Browser

Uploading

The SDK uses the File API to access files on the browser. It is highly recommended that you read this very well documented article about how to use it:
MDN: Using files from web applications

 

Once you get your hands on a File object you can use the upload method of the Documents service or of a PersistedDocument object. This method is very similar to the createChild method that we’ve already covered:

let file;

// ... get file

let appContext;

// ... get context

appContext.documents.upload( "parent-document/", file, "Optional Slug" ).then(
    ( [ fileMetadata, response ] ) => {
        console.log( fileMetadata.isResolved() ); // false

        // Resolve document with file's metadata
        return fileMetadata.resolve();
    }
).then(
    ( [ fileMetadata, response ] ) => {
        console.log( fileMetadata.size ); // E.g. 100634
        console.log( fileMetadata.mediaType ); // E.g. image/png
    }
).catch( console.error );
import * as App from "carbonldp/App";
import * as HTTP from "carbonldp/HTTP";
import * as PersistedDocument from "carbonldp/PersistedDocument";
import * as RDFRepresentation from "carbonldp/RDFRepresentation";

let file:File;

// ... get file

let appContext:App.Context;

// ... get context

appContext.documents.upload( "parent-document/", file, "Optional Slug" ).then(
    ( [ fileMetadata, response ]:[ PersistedDocument.Class, HTTP.Response.Class ] ) => {
        console.log( fileMetadata.isResolved() ); // false

        // Resolve document with file's metadata
        return fileMetadata.resolve<RDFRepresentation.Class>();
    }
).then(
    ( [ fileMetadata, response ]:[ RDFRepresentation.Class & PersistedDocument.Class, HTTP.Response.Class ] ) => {
        console.log( fileMetadata.size ); // E.g. 100634
        console.log( fileMetadata.mediaType ); // E.g. image/png
    }
).catch( console.error );
var file;
a
// ... get file

var appContext;

// ... get context

appContext.documents.upload( "parent-document/", file, "Optional Slug" ).then(
    function( result ) {
        var fileMetadata = result[ 0 ];
        var response = result[ 1 ];

        console.log( fileMetadata.isResolved() ); // false

        // Resolve document with file's metadata
        return fileMetadata.resolve();
    }
).then(
    function( result ) {
        var fileMetadata = result[ 0 ];
        var response = result[ 1 ];

        console.log( fileMetadata.size ); // E.g. 100634
        console.log( fileMetadata.mediaType ); // E.g. image/png
    }
).catch( console.error );
The promise returned by the method will contain an array with the file’s metadata as its first item (pretty much like the createChild method). Each time you upload a file a document gets created with the file’s metadata. The object you’ll receive will be an unresolved pointer to it, which you can resolve with the resolve method.

This document acts like a normal document. It can have children, members and even be a parent of other files. You can also add new data to it like you’d to any other document.

Tracking upload progress

Upload progress can be tracked using the optional options argument. You can pass an XMLHttpRequest through this argument with the request property:

let file;

// ... get file

let appContext;

// ... get context

let xhr = new XMLHttpRequest();
xhr.upload.addEventListener( "progress", ( event ) => {
    let incrementingPercentage:number = parseInt( event.loaded / event.total * 100 );
    let decrementingPercentage:number = 100 - incrementingPercentage;

    console.log( incrementingPercentage );
    console.log( decrementingPercentage );
} );

appContext.upload( "parent-document/", file, "Optional Slug", { request: xhr } ).then(
    ( [ fileMetadata, response ] ) => {
        // ...
    }
).catch( console.error );
import * as App from "carbonldp/App";
import * as HTTP from "carbonldp/HTTP";
import * as PersistedDocument from "carbonldp/PersistedDocument";
import * as RDFRepresentation from "carbonldp/RDFRepresentation";

let file:File;

// ... get file

let appContext:App.Context;

// ... get context

let xhr:XMLHttpRequest = new XMLHttpRequest();
xhr.upload.addEventListener( "progress", ( event:ProgressEvent ) => {
    let incrementingPercentage:number = parseInt( event.loaded / event.total * 100 );
    let decrementingPercentage:number = 100 - incrementingPercentage;

    console.log( incrementingPercentage );
    console.log( decrementingPercentage );
} );

appContext.upload( "parent-document/", file, "Optional Slug", { request: xhr } ).then(
    ( [ fileMetadata, response ]:[ PersistedDocument.Class, HTTP.Response.Class ] ) => {
        // ...
    }
).catch( console.error );
var file;

// ... get file

var appContext;

// ... get context

var xhr = new XMLHttpRequest();
xhr.upload.addEventListener( "progress", function( event ) {
    var incrementingPercentage:number = parseInt( event.loaded / event.total * 100 );
    var decrementingPercentage:number = 100 - incrementingPercentage;

    console.log( incrementingPercentage );
    console.log( decrementingPercentage );
} );

appContext.upload( "parent-document/", file, "Optional Slug", { request: xhr } ).then(
    function( result ) {
        // ...
    }
).catch( console.error );

Downloading

Files uploaded will get an id assigned. This id, like the one of any document, is going to be a resolvable URI. If you open it in a browser you’ll be able to download it.

However, if the file is protected by the security scheme, opening it on a browser will prompt for credentials. If you want to provide a link that uses the authentication you may already have in your application you can use the Auth service’s getAuthenticatedURL method.

This method will return a promise that when resolved will give you a URL with a temporary ticket to authenticate the current user for that request:

let fileMetadata;

// ... get a pointer to the file's metadata

let appContext;

// ... get app context

appContext.auth.getAuthenticatedURL( fileMetadata.id ).then(
    ( authenticatedFileURL ) => {
        window.open( authenticatedFileURL, "_blank" ); // Open the URL in another window to start the download
    }
);
import * as App from "carbonldp/App";
import * as PersistedDocument from "carbonldp/PersistedDocument";

let fileMetadata:PersistedDocument.Class;

// ... get a pointer to the file's metadata

let appContext:App.Context;

// ... get app context

appContext.auth.getAuthenticatedURL( fileMetadata.id ).then(
    ( authenticatedFileURL:string ) => {
        window.open( authenticatedFileURL, "_blank" ); // Open the URL in another window to start the download
    }
);
var fileMetadata;

// ... get a pointer to the file's metadata

var appContext;

// ... get app context

appContext.auth.getAuthenticatedURL( fileMetadata.id ).then(
    function( authenticatedFileURL ) {
        window.open( authenticatedFileURL, "_blank" ); // Open the URL in another window to start the download
    }
);

NodeJS

TO BE DOCUMENTED