Skip to content

Quickstart

Mathieu Savy edited this page Jun 13, 2016 · 13 revisions

Wakanda JavaScript Client - Quickstart

This quickstart aims to present all the main features of Wakanda Client, and how they works. The API is very close to the Angular-Wakanda one, so if you already know it, you will be on a known field.

All asynchronous methods return a promise, so you'll have to be familiar with it to use Wakanda Client.

Instantiating client

On a browser or on node, Wakanda Client is used the same. The only thing that differs is the way you include it on your projet. As it's exposed as a UMD module, you're free to use a various panel of module loader, or even this good old global variable on browser to use it.

On node for example

var WakandaClient = require('wakanda-client');

On a browser

<script src="/path/to/wakanda-client.min.js"></script>

Then, simply instantiate it. You have to pass an URI to indicate where is your Wakanda Server. On browser, you can omit this parameter, then all requests will be done on /rest/... address, so it's on you to proxy it to your Wakanda Server.

var wakanda = new WakandaClient.WakandaClient('http://localhost:8081');

ES6/TypeScript

You can also import exposed classes with import command.

import {WakandaClient} from 'wakanda-client';

let client = new WakandaClient();

On next examples, wakanda variable will designate an instance of WakandaClient.

Getting a catalog

Before working with dataClasses, you will need to retrieve it. A set of dataClasses is called a Catalog.

wakanda.getCatalog().then(function (ds) {
  //ds (for dataStore) is our catalog, it contains all ours dataClasses. For example:
  //ds.Company, ds.Employee, etc.
});

If you want only specific dataClasses, pass an array with dataClasses name to getCatalog

wakanda.getCatalog(['Company']).then(function (ds) {
  //ds.Company is defined, but ds.Employee is not
});

On next examples ds will designate a fully retrieved catalog.

Retrieving entities

Find

To find an entity with its key, use find method on a dataClass.

ds.Company.find(6)
  .then(function (company) {
    //company is an entity, with its properties and framework methods (see next parts for their documentation)
  })
  .catch(function () {
    //company not found
  });

Query

You can also find several entities (a collection) with query method. It takes an optional object as parameter to describe your query (order, expanding, filter, etc).

ds.Company.query({
  filter: 'staffCount > :1',
  params: [500],
  orderBy: 'name'
})
  .then(function (companyCollection) {
    var firstCompany = companyCollection.entities[0];
  });

There are some utility methods on collections (especially for paging), it will be described on the next parts.

Manipulating an entity

Saving

save() method on an entity will create or update it. If there is some server-side processing on the entity, it will be updated when the promise resolves.

ds.Employee.find(4).then(function (employee) {
  employee.firstName = 'Jack';
  employee.save().then(function () {
    //Our entity is updated
  });
});

Creating

To create an entity, call create() on the right dataClass, affect values for its properties then save it.

var newCompany = ds.Company.create();
company.name = 'Nice Corp';
company.save();

You can also pass an object as parameter to affect properties at the same time.

var newCompany = ds.Company.create({
  name: 'Nice Corp'
});
newCompany.save();

Delete

To delete an entity, call delete() on it.

ds.Company.find(5).then(function (company) {
  company.delete().then(function () {
    //company is deleted
  });
});

Related entities

Wakanda allows us to manipulate seamlessly related entities. We can affect, retrieve and access related entities with no pain.

Expanding

On a find or a query, we can use expand option to eagerly retrieve a related entity or a collection.

//Expanding an entity
ds.Employee.find(4, {expand: 'employer'}).then(function (employee) {
  var company = employee.employer;
  //company is a fully featured entity, we can manipulate it like the others
});

//Expanding a collection
ds.Company.find({
  orderBy: 'name',
  expand: 'staff'
})
  .then(function (companies) {
    var firstCompany = companies.entities[0];
    //firstCompany.staff is an employee collection
    var firstEmployeeOfTheFirstCompany = firstCompany.staff.entities[0];
  });

Fetching

To access a related entity or collection that have not been expanded, you can to fetch it with fetch() method. Before being fetched (or expanded), it's considered as deferred.

ds.Employee.find(4).then(function (employee) {
  employee.employer; //deferred entity

  employee.employer.fetch().then(function () {
    //employee.employer is now fetched and can be used like any other entity

    //it works the same for a collection
    employee.employer.staff.fetch().then(function () {
      //staff is now filled with its entities
    });
  });
});

Affecting

We can affect a related entity as any other scalar type, with an affectation.

ds.Company.find(4).then(function (company) {
  var newEmployee = ds.Employee.create({
    firstName: 'Jonh',
    lastName: 'Smith',
    employer: company
  };
  //or newEmployee.employer = company; It's the same
  newEmployee.save();
});

Image/Blob upload

Upload

Image and files (blob) can be affected to an entity thanks to upload() method. This method is present on every attributes of type image or blob. upload() method can only be called on an already saved entity, you can't call it just after a create(), because the entity has to exist on the server-side.

Considering the following HTML file:

<input type="file" id="fileInput" />
ds.Employee.find(12).then(function (employee) {
  var fileInput = document.getElementById('fileInput');
  var file = fileInput.files[0];

  employee.profilePicture.upload(file).then(function () {
    //file is uploaded and entity is updated
  });
});

Retrieve existing file

image and blob attributes are represented by an object, with the upload() method, and a uri property. This property carries the actual URI of the file, if there is one.

ds.Employee.find(12).then(function (employee) {
  //employee.profilePicture.uri
});

Remove the current file

To delete the current file affected to a image or blob attribute, you can call the delete() method on the property.

ds.Employee.find(12).then(function (employee) {
  employee.profilePicture.delete().then(function () {
    //The file has been deleted, and detached from the entity
  });
});

Collection helpers

There are several helpers on collection to make paging or infinite loading an easy task:

  • nextPage(): get the next page of the collection
  • prevPage(): get the previous page of the collection
  • more(): load a new page and append it to the current collection

Difference between more and nextPage is that more will add the retrieved entities to the current entities array, where nextPage will replace the actual entities with the retrieved ones.

All three methods return a promise and change the collection they are called on.

//Next page
ds.Company.query({pageSize: 10}).then(function (collection) {
  //When we want to next 10 entities
  collection.nextPage().then(function () {
    //collection.entities has now the 10 nexts
  });
});

//More
ds.Company.query({pageSize: 10}).then(function (collection) {
  //When we want 10 entities more (infinite loading you say?)
  collection.more().then(function () {
    //collection.entities has now the 20 entities
  });
});

Obviously, mixing nextPage and more will not result on something funny, you don't want to do that.

Server methods

On Wakanda, you can define methods on the model designer. It can be attached on DataClass, Entity or Collection.

You can directly call theses methods on the object you manipulate with Wakanda Client (excepting collection methods, that will be implemented soon).

//On an entity
ds.Company.find(3).then(function (company) {
  company.myEntityMethod().then(function (result) {
    //result will contain what have been return by the method (if any)
  });
});

//On a dataClass
ds.Company.myDataClassMethod().then(function (result) {
  
});

If the method defined on the server returns an entity or a collection, Wakanda Client will automatically consider the returned value as an entity or a collection.

ds.Company.methodThatReturnsAnEntity().then(function (result) {
  //result is an entity, we can manipulate that like any other entity
  result.foo = 'bar';
  result.save();
});

Directory methods

Wakanda-Clients allows you to use directory methods to authenticate. All those methods are accessible with the directory property of a WakandaClient instance.

To log in, use login() method.

wakanda.directory.login('username', 'password')
  .then(function () {
    //User is logged in
  })
  .catch(function (e) {
    //Login failed. Maybe bad credentials?
  });

You can set a duration in seconds as third parameter.

wakanda.directory.login('username', 'password', 86400) //session will be available for 24 hours

To logout, simply use logout() method.

wakanda.directory.logout()
  .then(function () {
    //logout with success
  });

To get the current user, use currentUser() method.

wakanda.directory.currentUser()
  .then(function (user) {
     //user.userName, user.fullName, user.ID
  });

To check if the current user belongs to a specific group, use currentUserBelongsTo() method.

wakanda.directory.currentUserBelongsTo('Admin')
  .then(function (result) {
    console.log('You are ' + (result ? '' : 'not ') + 'an admin');
  });