Restful + persistance: please help!

178 views
Skip to first unread message

Luis Gonzalez

unread,
Feb 12, 2013, 6:05:45 PM2/12/13
to Agility.js
I'm playing with the demo of persistence shown in the docs ( the one
that gathers data from api/people ).
Since the database I'm using is a MongoDB one, hosted in mongolab, I
have no way to design it in order to adhere to the default format
"GET: api/people".

The data is accessible through this url:
"https://api.mongolab.com/api/1/databases/friends/collections/school?
apiKey=4fdcfee7e4b0efd21e19e7ac"

So I created a route (using the Davis.js library) as follows:

this.get('/api/people', $.getJSON [url], function(data)
{ return data});

The problem is that somehow, the persistence plugin doesn't recognize
this route.
If I clink on a hard coded link pointing to "api/people", it works.
But calling "this.gather(person, 'append', 'ul') " just throw a "404
Not found" error message.

Why? Am I missing something?
Is there any restriction in persistence plugin for using client-side
routes?

Tom Lackner

unread,
Feb 12, 2013, 6:07:49 PM2/12/13
to agil...@googlegroups.com
Hey Luis,

Can you put your code up on JSBin or something so we can take a look? Your Network Inspector panel in Chrome would probably give you some more guidance as well..



--
You received this message because you are subscribed to the Google Groups "Agility.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to agilityjs+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.





--
Thomas Lackner * 305-978-8525
Message has been deleted
Message has been deleted
Message has been deleted

Luis Gonzalez

unread,
Feb 12, 2013, 9:29:31 PM2/12/13
to Agility.js
Hi Tom!

I got it published here: http://luismgz.appspot.com
All the necessary scripts (3) are linked from external sources
(jquery, agility and davis).
And my javascript code is here: http://luismgz.appspot.com/static/persapp.js
(Bellow, you can see the original coffeescript if you want...).

I tried replicating this set up in jsBin, but it didn't work.
It's here if you want to look: http://jsbin.com/isoqed/12/edit

By the way, it is exactly the demo script shown in the documentation.
I only added the routes.

Thanks!
Luis

cofreescript version:
---------------------------------------------------------------------------

$ ->
person = $$({}, '<li data-bind="name"/>').persist($
$.adapter.restful, {collection:'people'})
people = $$({
model: {}
view:
format:
"""<div>\
<span>Loading ...</span>\
<button>Load people</button><br/><br/>\
People: <ul/>\
</div>"""
style:
"""& {position:relative}\
& span {position:absolute; top:0; right:0; padding:3px
6px; background:red; color:white; display:none; }"""

controller:
'click button': ->
this.empty()
this.gather(person, 'append', 'ul')

'persist:start': ->
this.view.$('span').show()

'persist:stop': ->
this.view.$('span').hide()

}).persist()

url = 'https://api.mongolab.com/api/1/databases/friends/
collections/school?apiKey=4fdcfee7e4b0efd21e19e7ac'

app = Davis ->
this.configure -> this.generateRequestOnPageLoad = true
this.get '/', -> $$.document.append(people)
this.get '/api/people', -> $.getJSON url, (data)=> data
app.start()
---------------------------------------------------------------------------

elpi...@gmail.com

unread,
Feb 13, 2013, 9:30:44 PM2/13/13
to agil...@googlegroups.com
You should write your own adapter and see for _params.type and _parasm.data and replace to mongolab url

// RESTful JSON adapter using jQuery's ajax() from agility
  agility.adapter.restful = function(_params){
    var params = $.extend({
      dataType: 'json',
      url: (this._data.persist.baseUrl || 'api/') + this._data.persist.collection + (_params.id ? '/'+_params.id : '')
    }, _params);
    $.ajax(params);
  };

elpi...@gmail.com

unread,
Feb 13, 2013, 9:35:35 PM2/13/13
to agil...@googlegroups.com

you should be write your own adapter and reconstruct the url when _params.type='GET'. see the default adappter.

// RESTful JSON adapter using jQuery's ajax() from agility.js

  agility.adapter.restful = function(_params){
    var params = $.extend({
      dataType: 'json',
      url: (this._data.persist.baseUrl || 'api/') + this._data.persist.collection + (_params.id ? '/'+_params.id : '')
    }, _params);
    $.ajax(params);
  };

El martes, 12 de febrero de 2013 18:35:45 UTC-4:30, Luis Gonzalez escribió:
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

Luis Gonzalez

unread,
Feb 17, 2013, 2:24:55 AM2/17/13
to Agility.js
I apologize for posting so many confusing messages lately...
I deleted some of them.

The solution was, as suggested, modifying the restful adapter to suit
my needs.
I had some trouble because I know very little javascript.
Actually, I got into client side programming recently thanks to
Coffeescript, which makes javascript look like python...

The code below is somewhat redundant, but if anyone needs a restful
adapter for mongolab, this one works:

// RESTful JSON adapter using jQuery's ajax()

agility.adapter.restful = function(_params){

var params = $.extend({
id: (_params.data ? _params.data.id : _params.id),
contentType: "application/json;charset=utf-8",
}, _params);

params.data = params.data ? JSON.stringify(_params.data) : '';
if (_params.type === 'POST' && (_params.id != null)) {
params.type = 'PUT';
};
params.url = (this._data.persist.baseUrl || 'api/') +
this._data.persist.collection + (params.id ? '/'+params.id : '') + ('?
apiKey='+this._data.persist.apiKey || '');
$.ajax(params);

};


To use this adapter, one should declare objects as follows (example):

person = $$({}, '<li data-bind="name"/>').persist($$.adapter.restful,
{
baseUrl: 'https://api.mongolab.com/api/1/databases/friends/
collections/',
collection: 'school',
apiKey: '4fdcfee7e4b0efd21e19e7ac',
});

Lil

unread,
Mar 1, 2013, 5:19:29 AM3/1/13
to agil...@googlegroups.com
I got a question Luis !!!
Does your adapter use coffee script or not....'couse im not familiar with script-based languages!!! 

Luis Gonzalez

unread,
Mar 2, 2013, 1:19:59 AM3/2/13
to Agility.js
Hi Lil,

I'm not sure what you mean with "script based languages".
JavaScript is a dynamic, interpreted, scripting language. Coffeescript
is simply an alternative syntax for JavaScript. It's code must be
compiled down to JavaScript so, they are both basically the same
language.

I prefer Coffeescript to JavaScript, but no matter what language I
use, the end result is simply JavaScript.

Do you need any help with your adapter..?
> > collections/<https://api.mongolab.com/api/1/databases/friends/collections/>',

Lil

unread,
Mar 2, 2013, 4:00:05 AM3/2/13
to agil...@googlegroups.com

Thanks, I 'm so ignorant when it comes to this kind of languages that I make mistekes. I actually resolved my problem yesterday.
But... if you gentely give me a description of a non-standard adapter... that will do fine. ANy descriptions ar least, in the lines of code. 
THanks for answering Luis! Have a nice time !

Luis Gonzalez

unread,
Mar 3, 2013, 4:01:41 AM3/3/13
to Agility.js
Well, if you read the latest messages on this group, you'll see I had
a lot of trouble myself...

However, it all comes down to understanding how the persistence plugin
works and why we sometimes need custom adapters.
Agility is based on jQuery, and all the actions performed by the rest
adapter are simply wrappers for jQuery's Ajax function.

The standard ajax call with jQuery looks like this:

$.ajax({
url: [ your rest service URL here],
type: ["GET" for getting data, POST for adding, PUT for updating or
DELETE],
dataType: [json, xml, html...],
and other opcional parameters...
});

The built in persistente plugin assumes that the REST service you are
connecting to has an URL with the form "baseUrl/api/collectionName".
So if you write your own restful API in the server, and you want to
use persistence out of the box, you must create your urls this way.
For example, if you have a collection of people, your API should look
like this:

GET: /api/people (this returns all the persons in your people
collection).
GET: /api/people/id (this returns the person with the given id).
etc... (Look at Agility's docs where this is explained clearly).

However, sometimes you have to connect to a third party API, one
designed by someone else, whose URL doesn't fit this format.
In this case, you must write a custom adapter. The adapter is
responsible for modifying the parameters to the above Ajax call in
order to make it work.

If you look this same thread, I needed to write an adapter for
connecting to a mongolab database. This API had some specific
requirements.
For example, the URL should contain an API key at the end, so I
modified the adapter to get the API key from a parameter passed to
persistence, which is added at the end of the URL.

Any other modification needed to make persistence work with your
database should be done in your adapter.
The built-in adapter works only if your API's URL has the form
baseUrl / api / collection name.

If this is not the case, then a custom adapter is needed.
I hope this clerared up some stuff for you...

Luis

Lil

unread,
Mar 3, 2013, 4:57:43 AM3/3/13
to agil...@googlegroups.com
Yes , it cleared a lot! I thank you for your time ! :)
Reply all
Reply to author
Forward
0 new messages