Carbon LDP JavaScript SDK 101 – Save a document

f you’re new to programming with Carbon LDP, you will likely want to learn the bare essentials first – like CRUD operations (Create, Read, Update, Delete). In this post, I show how to use the Carbon LDP JavaScript SDK to create a document based on inputs from a simple UI form. Until we get a chance to improve the getting started guide, I hope this provides some additional context.

Input Form Example

First, take a look at the UI form I created for this exercise. The goal is to add click handler to the submit button, and the save a new document to Carbon based on the form’s values.

Input Form HTML

Nothing too fancy – just a simple form using Twitter Bootstrap.

<form>
    <div class="row">
        <div class="form-group col-xs-6">
            <label for="userName">Email (Login ID)</label>
            <input type="text" class="form-control" id="userName" value="cody@base22.com">
        </div>
        <div class="form-group col-xs-6">
            <label for="password">Password</label>
            <!-- Change to type="password" in a real-world scenario... -->
            <input type="text" class="form-control" id="password" value="password">
        </div>
    </div>
    <div class="form-group">
        <label for="contentTitle">Title</label>
        <input type="text" class="form-control" id="contentTitle" placeholder="Content Title">
    </div>
    <div class="form-group">
        <label for="editor1">Body</label>
        <textarea class="form-control" id="editor1" name="editor1" rows="10" cols="80">
         Write your brilliant words here.
        </textarea>
    </div>
    <div class="form-group">
        <label for="slug">Slug</label>
        <input type="text" class="form-control" id="contentSlug" placeholder="content-uri-slug">
    </div>
 
    <script>
        // Replace the <textarea id="editor1"> with a CKEditor
        // instance, using default configuration.
        CKEDITOR.replace( 'editor1' );
    </script>
    <p></p>
    <button type="button" class="btn btn-primary" id="submitButton">Submit</button>
</form>

JavaScript

I’ve included the following scripts on the page…

<script src="/javascript/moment.min.js"></script>
<!-- IE required polyfill -->
<!-- Copied by gulp copy-resources from node_modules/core-js/client/shim.js -->
<script src="/javascript/shim.min.js"></script>
<script src="/javascript/Carbon.sfx.js"></script>
  • moment.js – for generating a publish date in the ISO format I want.
  • shim.min.js – from core-js, which is a required polyfill for IE.
  • Carbon.sfx.js – Carbon supports ES6 and TypeScript, but this is the lib you need for plain-old JavaScript.

And here’s the entire working script I’ve placed below the form on the page to save the input to Carbon.

(function() {
 
    var APP_SLUG = 'test-app/';
     
    var carbon = new Carbon();
    carbon.setSetting( "domain", "localhost:8083" );
    carbon.setSetting( "http.ssl", false );
     
    function submitContent() {
         
        // Get all the values from the UI Form...
        // (No form validation going on here yet)
        var contentTitle = document.getElementById("contentTitle").value;
        var contentBody = CKEDITOR.instances.editor1.getData();
        var pubDate = moment().format();
        var contentSlug = document.getElementById("contentSlug").value;
        var userName = document.getElementById("userName").value;
        var password = document.getElementById("password").value;
 
        var myAppContext;
        var content;
 
        carbon.auth.authenticate( userName, password ).then(
            function( token ) {
                //console.log( "Authenticated Agent: %o",carbon.auth.authenticatedAgent ); // Yourself!
                return carbon.apps.getContext( APP_SLUG );
            }
        ).then(
            function( appContext ) {
                myAppContext = appContext; // retrieving your app context
 
                content = {
                    title: contentTitle,
                    body: contentBody,
                    publishedDate: pubDate
                };
                 
                return myAppContext.documents.createChild( "/", content, contentSlug );
            }
        ).then(
            function( result ) {
                var persistedContent = result[ 0 ];
                var response = result[ 1 ];
                 
                console.log( content === persistedContent ); // true
                console.log( "Created document: " + content.id ); // document's URI
            }
        ).catch( console.error );
         
    }
 
    var el = document.getElementById('submitButton');
    el.addEventListener("click", submitContent, false);
     
})();

This script does the following, in general:

  • Creates a new platform context (referencing my localhost dev instance of Carbon).
  • Defines a function to execute and attaches it to the submit button.
  • Within the function, we login to Carbon,
  • We get a handle on the particular Carbon application to save data to (test-app/),
  • We populate a simple JSON object with the values given by the form,
  • And then finally, we persist the JSON document in the root of the application using return myAppContext.documents.createChild( "/", content, contentSlug );

Viewing Documents in the Workbench

After submitting the form several times to create test documents, I am then able to check for the documents using the Carbon Workbench as shown below…

GET a Document by URI

I can also use my web browser or a REST client to get at any of the individual documents by URI. Following is an example of one of the documents, which I requested to be returned in JSON-LD.

[ {
  "@graph" : [ {
    "@id" : "http://localhost:8083/apps/test-app/test-26/",
    "@type" : [ "http://www.w3.org/ns/ldp#BasicContainer", "http://www.w3.org/ns/ldp#Container", "http://www.w3.org/ns/ldp#RDFSource", "https://carbonldp.com/ns/v1/security#ProtectedDocument" ],
    "http://localhost:8083/apps/test-app/vocabulary/#body" : [ {
      "@value" : "<p>This is my textarea to be replaced with CKEditor.</p>\n"
    } ],
    "http://localhost:8083/apps/test-app/vocabulary/#publishedDate" : [ {
      "@value" : "2016-09-02T16:37:03-05:00"
    } ],
    "http://localhost:8083/apps/test-app/vocabulary/#title" : [ {
      "@value" : "Test 26"
    } ],
    "http://www.w3.org/ns/ldp#hasMemberRelation" : [ {
      "@id" : "http://www.w3.org/ns/ldp#member"
    } ],
    "https://carbonldp.com/ns/v1/platform#created" : [ {
      "@type" : "http://www.w3.org/2001/XMLSchema#dateTime",
      "@value" : "2016-09-02T21:37:03.925Z"
    } ],
    "https://carbonldp.com/ns/v1/platform#defaultInteractionModel" : [ {
      "@id" : "http://www.w3.org/ns/ldp#RDFSource"
    } ],
    "https://carbonldp.com/ns/v1/platform#modified" : [ {
      "@type" : "http://www.w3.org/2001/XMLSchema#dateTime",
      "@value" : "2016-09-02T21:37:03.925Z"
    } ],
    "https://carbonldp.com/ns/v1/security#accessControlList" : [ {
      "@id" : "http://localhost:8083/apps/test-app/test-26/~acl/"
    } ]
  } ],
  "@id" : "http://localhost:8083/apps/test-app/test-26/"
} ]

Notice that Carbon automatically generated a vocabulary for the attributes of the JSON object I gave it. For example, for the title, Carbon created the property URI, http://localhost:8083/apps/test-app/vocabulary/#title. Carbon provides a means to use existing vocabularies and to create specific vocabulary URIs of own, but as you can see, you don’t have to.