odata

0.4.0 • Public • Published

o.js

o.js beta v0.4.0

o.js is a client side Odata Javascript library to simplify the request of data. The main goal is to build a standalone, lightweight and easy to understand Odata lib.

Install

Download the o.js or o.min.js file or install it via bower:

bower install o.js

Then you can add the script into your file (<script src="bower_components/o.js/o.js"></script>), or load it with your favorite AMD loader:

require.config({paths: {'odata': 'bower_components/o.js/o'}});
define(['odata'], function(o) {...});

You can use o.js in node.js as well, by installing the odata package:

npm install odata
var o = require('odata');

Samples

For all samples we are using the test odata service from Odata.org. You can find the metadata of this service here.

Simple Odata query with o.js

o('http://services.odata.org/V4/OData/OData.svc/Products').get(function(data) {
  console.log(data); //returns an array of Product data
}, function(status) {
  console.error(status); // error with status
});

o.js uses a jQuery like syntax to determine which resource you want to access. You can define any Odata service url (or any json web service) in the o-function: o('<your odata service resource>'). This only holds a handler to this resource and doesn't start the ajax call. If you want to get the resource, you need to call .get(). Get accepts a function callback which contains the data as the first parameter.

Methods

By adding some chained functions to the o-handler you can add query options:

o('http://services.odata.org/V4/OData/OData.svc/Products').take(5).skip(2).get(function(data) {
  console.log(data); //An array of 5 products skipped by 2
}, function(status) {
  console.error(status); // error with status
});

Routing

You can use hash routes to map your Odata service endpoint to your website:

o('http://services.odata.org/V4/OData/OData.svc/Products').find(':0').route('Product/Detail/:0/:1',function(data) {
  console.log('Route Product/Detail/'+this.param[0]+'/'+this.param[1]+' triggered. Result:');
  console.log(data);
});

Instead of manual getting your data with the get() function, this routing function always returns the data when somebody navigates to an URL with the hash value index.html#Product/Detail/1/Some more parameter. The find() method automatically maps the right parameter (in this example 1). See this demonstration for more examples.

Get data (details)

If you want to get data you need to call the get() function. This functions returns an async callback function which holds an array as it's parameter. If you use first() or the find() method it only returns the data because an array is not needed. You can also save your o-function to call it later:

var oHandler = o('http://services.odata.org/V4/OData/OData.svc/Products');
//do something
oHandler.find(1);
// do some more
 
//get the data
oHandler.get(function(data) {
  console.log(data);
  //or the saved var also contains the data:
  console.log(oHandler.data);
}, function(status) {
  console.error(status); // error with status
});

If you need to get several data you can use promise. Currently o.js only supports q.js. The following example show how you can get the data of two different resources:

Q.all([
  o('http://services.odata.org/V4/OData/OData.svc/Products(4)').get(),
  o('http://services.odata.org/V4/OData/OData.svc/Categories').take(2).get()
]).then(function(oHandlerArray) {
  //The oHandler array contains the Product oHandler and the Group oHandler:
  oHandlerArray[0].data); // 1 Product with id 4
  oHandlerArray[1].data.length); // 2 Categories
});

You can also use promise for only one resource. The main advantage is, that you can use a fail-function:

o('http://services.odata.org/V4/OData/OData.svc/Products(2)').get().then(function(oHandler) {
  console.log(oHandler.data);
}).fail(function(ex) {
  console.log(ex);
});

Add and change data

To add and change data you can use the http verb in combination with the save() method:

Post:

You can use the post() function in combination with the save() method to add data:

o('http://services.odata.org/V4/OData/OData.svc/Products').post({Name:'Example 1',Description:'a'}).post({Name:'Example 2',Description:'b'}).save(function(data) {
  console.log("Two Products added");
}, function(status) {
  console.error(status); // error with status
});

Patch/Put:

Changing (PATCH or PUT) data is nearly the same:

o('http://services.odata.org/V4/OData/OData.svc/Products(1)').patch({Name:'NewName'}).save(function(data) {
  console.log("Product Name changed");
}, function(status) {
  console.error(status); // error with status
});

Delete:

To remove (DELETE) data you need to call remove():

o('http://services.odata.org/V4/OData/OData.svc/Products(1)').remove().save(function(data) {
  console.log("Product deleted");
}, function(status) {
  console.error(status); // error with status
});

Reference:

To add an reference to an other resource use ref (to remove it simply use removeRef the same way):

o('http://services.odata.org/V4/OData/OData.svc/Products(1)').ref('Categories', 2).save(function(data) {
  console.log("Products(1) associated with Categories(2)");
}, function(status) {
  console.error(status); // error with status
});

If the navigation property you are trying to set is not named the same as the collection:

o('http://services.odata.org/V4/OData/OData.svc/Products(1)').ref('RelatedProducts', 'Products', 2).save(function(data) {
  console.log("Products(1) associated with Products(2) using the RelatedProducts navigation property");
}, function(status) {
  console.error(status); // error with status
});

You can also combine a single data request (first() or find()) with the save method and chain it:

o('http://services.odata.org/V4/OData/OData.svc/Products').find(2).get().then(function(oHandler) {
  oHandler.data.Name="NewName";
  return(o.save());
}).then(function(oHandler) {
  console.log(oHandler.data.Name); //NewName
}).fail(function(ex) {
  console.log("error");
});

Endpoint configuration

You can configure a endpoint with the o().config() function. This configuration is persistent over all off your o.js calls. Example:

// set an endpoint
o().config({
  endpoint:'http://services.odata.org/V4/OData/OData.svc'
});
 
// after you have set an endpoint, you can shorten your queries:
o('Products').get(function(data) {
  //same result like the first example on this page
}, function(status) {
  console.error(status); // error with status
});

However, if you have set an endpoint you can still do a full endpoint request for example to another domain o('http://odata.example.de/Customer'). With this function you can also do some more basic configs:

//basic config
o().config({
    endpoint: null,   // The default endpoint to use.
    format: 'json',  // The media format. Default is JSON.
    autoFormat: true,   // Will always append a $format=json to each query if set to true.
    version: 4,  // currently only tested for Version 4. Most will work in version 3 as well.
    strictMode: true,  // strict mode throws exception, non strict mode only logs them
    start: null,  // a function which is executed on loading
    ready: null, // a function which is executed on ready
    error: null, // a function which is executed on error
    headers: [], // an array of additional headers [{name:'headername',value:'headervalue'}]
    username: null,  // the basic auth username
    password: null, // the basic auth password
    isAsync: true // set this to false to enable sync requests. Only usable without basic auth
      isWithCredentials: false,       // set this to true to use basic auth
    isHashRoute: true,  // set this var to false to disable automatic #-hash setting on routes
    appending: '' // set this value to append something to a any request. eg.: [{name:'apikey', value:'xyz'}]
});

Full list of supported functions

Currently the following queries are supported:

.find(int) - returns the object with the given id. (Odata: Products_(1)_)

.top(int) - returns the top x objects (Odata: Products/?$top=2) - Synonym: .take

.skip(int) - returns the objects skipped by the given value (Odata: Products/?$skip=2)

.first() - returns the first object which is found (Odata: Products/?$top=1)

.filter(string) - adds a filter string (o.js can converted simple JS-Syntax. If you need something complex use the plain Odata $filter syntax: see the Odata doc for more information) (Odata: Products/?$filter=Name eq 'Example') - Synonym: .where

.any(string, string) - applies an any filter to an resource (Odata: Products/?$filter=Categories/any(x:x/Name eq 'Test'))

.search(array, string) - builds up a search $filter. The first parameter defines the columns to search in the second the search word (e.g.: .search(['Name', 'Description'], 'Test'))

.orderBy(string, direction) - orders the data (Odata: Products/?$orderBy=Name)

.orderByDesc(string) - orders the data descending (Odata: Products/?$orderBy=Name)

.count() - only counts the result (Odata: Products/$count)

.inlineCount(string) - adds a inlinecount to the result. (Odata: Products/?$count=true)

.batch(string) - adds a second resource to the request (Odata: $batch)

.expand(string) - expands a related resource (Odata: Products/?$expand=ProductUnit)

.select(string) - selects only certain properties (Odata: Products/?_$select=Name)

.ref(string, string, [string]) - expands a related resource (Odata: Products(1)/Category/$ref=Categories(1))

.deleteRef(string, string, [string]) - expands a related resource (Odata: Products(1)/Category/$ref=Categories(1))

.post(object) - Post data to an endpoint

.patch(object) - PATCH data on an endpoint

.put(object) - PUT data on an endpoint

.remove(object) - DELETE data on an endpoint (You must define only one resource: e.g: Products(1) )

.query() - get the query as string

.raw - gives the raw data in a callback

.xhr - allows access to the xhr object to get headers

Keywords

none

install

npm i odata

Downloadsweekly downloads

123

version

0.4.0

license

MIT

homepage

github.com

repository

Gitgithub

last publish

collaborators

  • avatar
  • avatar
  • avatar
Report a vulnerability