Angular.js RESTful API with fallback to PouchDB when offline.
Install with Bower:
$ bower install syonet.model
Inject syonet.model
module into your app:
angular.module( "app", [ "syonet.model" ] );
Then, inject the model
service in any controller:
angular.module( "app" ).controller( "MyController", function ( model ) {
model( "foo" ).id( "bar" ).save({
baz: "qux",
creationDate: new Date()
}).then(function ( document ) {
// Document is now persisted!
console.log( document );
});
});
Every method in the model
service will return a promise which is also an event emitter.
This means those promises will borrow the following API:
Add a listener listener
for event
event. listener
will receive the following arguments:
event
: An object that stores data related to the triggered event, e.g. the event type viatype
property.args...
: One or more custom arguments passed to the listeners.
Emit event
using the provided list of args
.
Also, when you invoke .then()
in this promise, it'll keep the event emitter interface with the
same listeners from the original promise.
All these methods will emit the following events:
cache
- when the cache is hit. Normally, the only argument passed is the cached value.server
- when the server response is received. Normally, the only argument passed is the received value.
Returns a new Model instance for the name
collection.
Provides access to the underlying PouchDB instance.
Get the ID of the current element, or create a new child element with the specified ID and return it
var user = model( "user" ).id( 100 );
console.log( user.id() ); // prints 100
Create a new child model and return it.
If model
is another instance, then the paths will be combined. Otherwise, a model for the given collection will be created.
Return a promise for the current revision of the element, or null
if no revision is found.
This method will throw an Error
if invoked in a collection.
Return the URL for the current model, including its base URL. If the ID is an array, they're joined with a comma ,
.
Example:
model( "foo" ).id( "bar" ).toURL(); // => /foo/bar
Lists all elements from a collection, and reutrns a promise for it. Triggers a GET
request and saves the result to the PouchDB cache.
If this method is invoked in an element, then passing the collection
argument is mandatory.
The query
argument is passed as query string parameters for the request.
If the request fails with HTTP code 0
, then the promise is resolved with the cached value.
If the same request has never been made before, the promise will be rejected.
Events
server
: fired when the server request is successful;cache
: fired when the cached is hit;
Example:
model( "foo" ).list({ bar: "baz" }); // GET /foo?bar=baz
model( "foo" ).id( "bar" ).list( "baz" ); // GET /foo/bar/baz
Get a element and returns a promise for it. Triggers a GET
request and saves the result to the PouchDB cache.
If this method is invoked in an collection, then passing the id
argument is mandatory.
If the request fails with HTTP code 0
, then the cached element is returned.
Example:
model( "foo" ).get( "bar" ); // GET /foo/bar
model( "foo" ).id( "bar" ).get(); // GET /foo/bar
Events
server
: fired when the server request is successful;cache
: fired when the cached is hit;
Create one or more elements return a promise for it. Triggers a POST
request and saves the result to the PouchDB cache.
If this method is invoked in an element, then passing the collection
argument is mandatory.
If the HTTP request fails with code 0
, then the elements passed will be created an assigned an temporary ID.
Example:
model( "foo" ).id( "bar" ).create( "baz" {
foo: "bar"
});
// POST /foo/bar/baz
// { foo: "bar" }
// Batch create
model( "foo" ).create([{
foo: "bar"
}, {
foo: "baz"
]);
// POST /foo
// [...]
Events
server
: fired when the server request is successful;cache
: fired when the cache is updated;
Update one or more elements and return a promise for it. Triggers a POST
request and saves the result to the PouchDB cache.
If this method is invoked in an collection, then it's mandatory to make a batch operation, using data
as an array.
If the HTTP request fails with code 0
, then the cached data will be replaced with the elements passed.
Example:
model( "foo" ).id( "bar" ).update({
foo: "bar"
});
// POST /foo/bar
// { foo: "bar" }
// Batch patch
model( "foo" ).update([{
id: 1,
foo: "bar"
}, {
id: 2,
foo: "baz"
]);
// POST /foo
// [...]
Events
server
: fired when the server request is successful;cache
: fired when the cache is updated;
Patch one or more elements and return a promise for it. Triggers a PATCH
request and saves the result to the PouchDB cache.
If this method is invoked in an collection, then it's mandatory to make a batch operation, using data
as an array.
If the HTTP request fails with code 0
, then the cached data will be extended with the elements passed.
Example:
model( "foo" ).id( "bar" ).patch({
foo: "bar"
});
// PATCH /foo/bar
// { foo: "bar" }
// Batch patch
model( "foo" ).patch([{
id: 1,
foo: "bar"
}, {
id: 2,
foo: "baz"
]);
// PATCH /foo
// [...]
Events
server
: fired when the server request is successful;cache
: fired when the cache is updated;
Remove an element or collection and returns a promise for it. Triggers a DELETE
request and wipes the
corresponding elements from the PouchDB cache.
Example:
model( "foo" ).remove(); // => DELETE /foo
model( "foo" ).id( "bar" ).remove(); // => DELETE /foo/bar
Events
server
: fired when the server request is successful;cache
: fired when the cache is updated;
Get or set the base URL for the HTTP requests.
model.base( "/api" );
model( "foo" ).list(); // GET /api/foo
model.base(); // /api
Attention: When setting a new value, existing cached data will be removed!.
Get or set Basic authentication for HTTP requests. If username
is not defined, then the existing
auth data will be returned.
model.auth( "foo", "bar" );
model( "foo" ).list(); // GET /foo with header Authorization: Basic <...>
model.auth(); // { username: "foo", password: "bar" }
Access to the modelProvider
API is given your config phase.
Usage:
angular.module(...).config(function ( modelProvider ) {
// Use modelProvider API in config block
}).provider( "foo", function ( modelProvider ) {
// Use modelProvider API in provider
this.$get = function () { ... };
});
Set this value to true
to allow the pluralization of collections in URLs.
// in your config phase
modelProvider.pluralizeCollections = true;
// in your controller or service
model( "foo" ).list() // => /foos
model( "foo" ).id( 1 ).list() // => /foo/1
model( "foo" ).model( "bar" ).list() // => /foos/bars
MIT