PDA

View Full Version : Query Odata Feed



vtmac
16 Mar 2011, 9:52 AM
Hi,

is it possible to query a odata feed using Ext.data.Store ?
I keep getting an parse error.
Anyone knows how to do it ?

thanks

mitchellsimoens
16 Mar 2011, 11:08 AM
More than likely. What does the feed look like? Got a URL?

vtmac
16 Mar 2011, 5:22 PM
Thanks for your fast reply.
For now its an internal odata feed.
But its prety much like this one :
http://services.odata.org/Northwind/Northwind.svc/
http://services.odata.org/Northwind/Northwind.svc/Customers?$format=json
if you can show me for example how to load the Customers (json format) to a data store to use it on a list would be awsome !

Thanks in advance!

StaticVoidMain
21 Mar 2011, 9:24 AM
For querying you don't need much, the problem arises when you want to write to the store but, if it is just for reading you just need to configure store like this:
var store = new Ext.data.JsonStore({
root: 'd',
url: 'http://services.odata.org/Northwind/Northwind.svc/Customers?$format=json',
fields:[...],
...
});
This works as expected, i'm using it, i'm also working on an "OdataStore" (and corresponding OdataProxy) to support writing but is not finnished yet.

I hope that helps a bit to clarify things.

JeremyCaney
9 Apr 2011, 1:41 PM
We did some work on querying an OData store back with ExtJS 3.0 and ADO.NET Data Services 1.5. I hope to update this to work with ExtJS 4.0 and WCF Data Services at some point, but haven't had a chance to work on this yet. One of my co-workers posted some information on the approach we took previously, which may be of value.

http://blogs.ignia.com/Levi.Fleischman/archive/2009/09/10/extjs.dataservices.rest.aspx

Jeremy

deepmime
10 Jun 2011, 2:19 PM
I plan on implementing this in the next month or so.

If anyone else is working on this, please let me know. I would rather not reinvent the wheel but it will be good practice for me if anything.

Any suggestions would be greatly appreciated. I think the trick will be updating I believe.

If i'm successful, i'll post the link here.

dotnetwise
12 Jun 2011, 7:46 AM
I'm also interestead into it for Ext 4.0.2 - any progress so far?

jcranwellward
12 Sep 2011, 8:44 AM
Bump!

Im also interested in this topic, anything happend this year yet?

facorreia
8 Nov 2011, 10:22 AM
I need to build front-end applications for WCF Data Services web services using the OData protocol.

Is there any progress on a compatible store for this with CRUD support?

Oleg Dolzhansky
12 Nov 2011, 5:56 AM
Please see this very basic implementation of OData Protocol which WCF Data Services use.

This Proxy support CRUD operations and sorting.



/*

Open Data Protocol Implementation for Ext Js 4
Links:
ExtJs 4 Server Proxy: http://docs.sencha.com/ext-js/4-0/source/Server.html#Ext-data-proxy-Server
ExtJs 4 Ajax Proxy: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Ajax
OData URI Conventions: http://www.odata.org/developers/protocols/uri-conventions
License: GNU General Public License v3 http://www.gnu.org/copyleft/gpl.html
Author: Oleg Dolzhansky dolzhansky@gmail.com

Example:

Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int', defaultValue: 0},
{name: 'name', type: 'string'}
],
idProperty: 'id'
});

var CustomersStore = Ext.create('Ext.data.Store', {
model: 'Customer',
proxy: {
type: 'odata',
url : '/Service.svc/Customers'
},
autoLoad: true
});

*/

Ext.define('Ext.ux.data.proxy.OData', {
extend: 'Ext.data.proxy.Ajax',
alternateClassName: 'Ext.ux.data.ProxyOData',
alias: 'proxy.odata',

/* Builds URL in the form Entity(Id), for example http://localhost/Service.svc/Customers(5) */
buildUrl: function (request) {
var me = this,
operation = request.operation,
records = operation.records || [],
record = records[0],
url = me.getUrl(request),
id = record ? record.getId() : operation.id;

if (id) {
if (url.match(/\/$/)) {
url = url.substring(0, url.length - 1);
}
url = url + '(' + id + ')';
}

request.url = url;

return me.callParent(arguments);
},

/* Returns a string of comma-separated fields from sortes with optional 'desc' directive */
encodeSorters: function (sorters) {
var min = [],
length = sorters.length,
i = 0;

for (; i < length; i++) {
min[i] = sorters[i].property;
if (sorters[i].direction.toLowerCase() == 'desc') {
min[i] += ' desc';
}
}

return min.join(',');
}

}, function () {
Ext.apply(this.prototype, {
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
},
reader: {
type: 'json',
root: 'd'
},
headers: {
'Accept': 'application/json'
},
pageParam: undefined,
startParam: '$skip',
limitParam: '$top',
sortParam: '$orderby',
noCache: false
});
});

Luc
12 Jan 2012, 6:34 AM
Hi,

I developed another ODataProxy for Sencha Touch 1.1 (not tested on ExtJs4). It was designed for use with SharePoint ListData service, which uses the OData protocol. It should work with other OData sources. It provides support for all CRUD operations, etag handling to do partial updates and fixes some issues in the ST data package.

You can find it at: https://github.com/lstak/SharePoint-proxy-for-Sencha-Touch

necco
13 Mar 2012, 5:11 AM
Please see this very basic implementation of OData Protocol which WCF Data Services use.

This Proxy support CRUD operations and sorting.



/*

Open Data Protocol Implementation for Ext Js 4
Links:
ExtJs 4 Server Proxy: http://docs.sencha.com/ext-js/4-0/source/Server.html#Ext-data-proxy-Server
ExtJs 4 Ajax Proxy: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Ajax
OData URI Conventions: http://www.odata.org/developers/protocols/uri-conventions
License: GNU General Public License v3 http://www.gnu.org/copyleft/gpl.html
Author: Oleg Dolzhansky dolzhansky@gmail.com

Example:

Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int', defaultValue: 0},
{name: 'name', type: 'string'}
],
idProperty: 'id'
});

var CustomersStore = Ext.create('Ext.data.Store', {
model: 'Customer',
proxy: {
type: 'odata',
url : '/Service.svc/Customers'
},
autoLoad: true
});

*/

Ext.define('Ext.ux.data.proxy.OData', {
extend: 'Ext.data.proxy.Ajax',
alternateClassName: 'Ext.ux.data.ProxyOData',
alias: 'proxy.odata',

/* Builds URL in the form Entity(Id), for example http://localhost/Service.svc/Customers(5) */
buildUrl: function (request) {
var me = this,
operation = request.operation,
records = operation.records || [],
record = records[0],
url = me.getUrl(request),
id = record ? record.getId() : operation.id;

if (id) {
if (url.match(/\/$/)) {
url = url.substring(0, url.length - 1);
}
url = url + '(' + id + ')';
}

request.url = url;

return me.callParent(arguments);
},

/* Returns a string of comma-separated fields from sortes with optional 'desc' directive */
encodeSorters: function (sorters) {
var min = [],
length = sorters.length,
i = 0;

for (; i < length; i++) {
min[i] = sorters[i].property;
if (sorters[i].direction.toLowerCase() == 'desc') {
min[i] += ' desc';
}
}

return min.join(',');
}

}, function () {
Ext.apply(this.prototype, {
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
},
reader: {
type: 'json',
root: 'd'
},
headers: {
'Accept': 'application/json'
},
pageParam: undefined,
startParam: '$skip',
limitParam: '$top',
sortParam: '$orderby',
noCache: false
});
});


hi

I tried to use your odata proxy but no results... the error is: Uncaught TypeError: Cannot read property 'records' of undefined in line 42 of odataproxy.js

Trying to extend Ext.data.proxy.JsonP instead of Ext.data.proxy.Ajax I receive the same error.

Oleg Dolzhansky
14 Mar 2012, 1:00 AM
Hi Necco,

My idea is that your request.operation could be undefined for some reason. What kind of operation are you trying to perform? Can you post the code so it can be troubleshooted?

I also changed the code a little, so it can count the records when reading:



/*

Open Data Protocol Implementation for Ext Js 4
Links:
ExtJs 4 Server Proxy: http://docs.sencha.com/ext-js/4-0/source/Server.html#Ext-data-proxy-Server
ExtJs 4 Ajax Proxy: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Ajax
OData URI Conventions: http://www.odata.org/developers/protocols/uri-conventions
License: GNU General Public License v3 http://www.gnu.org/copyleft/gpl.html
Author: Oleg Dolzhansky dolzhansky@gmail.com

Example:

Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int', defaultValue: 0},
{name: 'name', type: 'string'}
],
idProperty: 'id'
});

var CustomersStore = Ext.create('Ext.data.Store', {
model: 'Customer',
proxy: {
type: 'odata',
url : '/Service.svc/Customers'
},
autoLoad: true
});

*/

Ext.define('Ext.ux.data.reader.OData',{
extend: 'Ext.data.reader.Json',
alternateClassName: 'Ext.ux.data.ReaderOData',
alias: 'reader.odata',
root: 'd',
totalProperty: 'd.__count',
buildExtractors : function() {
var me = this;
me.callParent(arguments);
me.getRoot = function(root) {
if (root.d) {
if (root.d.results) {return root.d.results; }
else { return root.d; }
}
else { return root; }
};
}
});

Ext.define('Ext.ux.data.proxy.OData', {
extend: 'Ext.data.proxy.Ajax',
alternateClassName: 'Ext.ux.data.ProxyOData',
alias: 'proxy.odata',
/* Builds URL in the form Entity(Id), for example http://localhost/Service.svc/Customers(5) */
buildUrl: function (request) {
var me = this,
operation = request.operation,
records = operation.records || [],
record = records[0],
url = me.getUrl(request),
id = record ? record.getId() : operation.id;

if (id) {
if (url.match(/\/$/)) {
url = url.substring(0, url.length - 1);
}
url = url + '(' + id + ')';
}
if (request.action == 'read') {
request.params = Ext.apply(request.params, {'$inlinecount': 'allpages'});
}

request.url = url;

return me.callParent(arguments);
},

/* Returns a string of comma-separated fields from sortes with optional 'desc' directive */
encodeSorters: function (sorters) {
var min = [],
length = sorters.length,
i = 0;

for (; i < length; i++) {
min[i] = sorters[i].property;
if (sorters[i].direction.toLowerCase() == 'desc') {
min[i] += ' desc';
}
}

return min.join(',');
}

}, function () {
Ext.apply(this.prototype, {
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
},
reader: {
type: 'odata'
},
headers: {
'Accept': 'application/json'
},
pageParam: undefined,
startParam: '$skip',
limitParam: '$top',
sortParam: '$orderby',
noCache: false
});
});

necco
14 Mar 2012, 2:00 AM
hi Oleg,
Thanks for your prompt reply.
I'm trying to use your's proxy.odata with Sencha Touch 2.0... just a simple DataView List added to Viewport for the beginning (to see how it works because I want to use odata for a future app).

Is your proxy.odata working with Sencha Touch 2.0 or only with ExtJS 4?

index.html


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>DataLight Rapoarte Web</title>
<link href="img/icon_16.png" rel="shortcut icon" type="image/x-icon" />
<link rel="stylesheet" href="css/sencha-touch.css" type="text/css">
<script type="text/javascript" src="sencha/builds/sencha-touch-all-debug.js"></script>
<script type="text/javascript" src="proxyOData.js"></script>
<script type="text/javascript" src="lista.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
</body>
</html>


proxyOData.js



/*
/*
Open Data Protocol Implementation for Ext Js 4Links:ExtJs 4 Server Proxy: http://docs.sencha.com/ext-js/4-0/source/Server.html#Ext-data-proxy-ServerExtJs 4 Ajax Proxy: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.AjaxOData URI Conventions: http://www.odata.org/developers/protocols/uri-conventionsLicense: GNU General Public License v3 http://www.gnu.org/copyleft/gpl.htmlAuthor: Oleg Dolzhansky dolzhansky@gmail.com
Example:
Ext.define('Customer', { extend: 'Ext.data.Model', fields: [ {name: 'id', type: 'int', defaultValue: 0}, {name: 'name', type: 'string'} ], idProperty: 'id'});
var CustomersStore = Ext.create('Ext.data.Store', { model: 'Customer', proxy: { type: 'odata', url : '/Service.svc/Customers' }, autoLoad: true});
*/
Ext.define('Ext.ux.data.reader.OData',{ extend: 'Ext.data.reader.Json', alternateClassName: 'Ext.ux.data.ReaderOData', alias: 'reader.odata', root: 'd', totalProperty: 'd.__count', buildExtractors : function() { var me = this; me.callParent(arguments); me.getRoot = function(root) { if (root.d) { if (root.d.results) {return root.d.results; } else { return root.d; } } else { return root; } }; }});
Ext.define('Ext.ux.data.proxy.OData', { extend: 'Ext.data.proxy.Ajax', alternateClassName: 'Ext.ux.data.ProxyOData', alias: 'proxy.odata', /* Builds URL in the form Entity(Id), for example http://localhost/Service.svc/Customers(5) */ buildUrl: function (request) { var me = this, operation = request.operation, records = operation.records || [], record = records[0], url = me.getUrl(request), id = record ? record.getId() : operation.id;
if (id) { if (url.match(/\/$/)) { url = url.substring(0, url.length - 1); } url = url + '(' + id + ')'; } if (request.action == 'read') { request.params = Ext.apply(request.params, {'$inlinecount': 'allpages'}); }
request.url = url; return me.callParent(arguments); },
/* Returns a string of comma-separated fields from sortes with optional 'desc' directive */ encodeSorters: function (sorters) { var min = [], length = sorters.length, i = 0;
for (; i < length; i++) { min[i] = sorters[i].property; if (sorters[i].direction.toLowerCase() == 'desc') { min[i] += ' desc'; } }
return min.join(','); }
}, function () { Ext.apply(this.prototype, { actionMethods: { create: 'POST', read: 'GET', update: 'PUT', destroy: 'DELETE' }, reader: { type: 'odata' }, headers: { 'Accept': 'application/json' }, pageParam: undefined, startParam: '$skip', limitParam: '$top', sortParam: '$orderby', noCache: false });});

lista.js



Ext.define('Customer', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int', defaultValue: 0},
//{name: 'City', type: 'string'}
{name: 'CODAGENT', type: 'string'} ]
,idProperty: 'id' });
var customersStore = Ext.create('Ext.data.Store', {
model: 'Customer',
proxy: {
type: 'odata', //url : '/Service.svc/Customers'
url: 'http://192.168.1.223/ro2/odata/DataLightERP/CRM/agenti?$format=json' },
autoLoad: true });

var listaParteneri = Ext.create('Ext.dataview.List',{ui: 'round',
pinHeaders: false,
//itemTpl: '<div class="contact"><strong>{NUMEAGENT}</strong></div>',
store: customersStore,
emptyText: '<div style="margin-top: 20px; text-align: center">No Matching Items</div>',
items: [ {
xtype: 'toolbar',
docked: 'top',
items: [{ xtype: 'spacer' },
{
xtype: 'searchfield',
placeHolder: 'Cauta partenerul...',
listeners: {//scope: this,
//clearicontap: function(){onSearchClearIconTap(store)},
//keyup: function(){onSearchKeyUp(this.getValue(),store)}
}
},
{xtype: 'spacer'}
]
}
]
,listeners: {
select: function(){
alert('Selected');
}
}
});


var listPanel = Ext.create('Ext.Panel',{
width: 280,
height: 520,
centered: true,
modal: true,
hideOnMaskTap: true,
layout: 'fit',
items:[listaParteneri]
});


app.js



Ext.application({name: 'ComenziWeb'
,tabletStartupScreen: 'resources/img/tablet_startup_atto.png'
,phoneStartupScreen: 'resources/img/phone_startup_atto.png'
,icon: 'resources/img/icon_atto.png'
,glossOnIcon: false
,launch: function(){
Ext.Viewport.add(listPanel);
}});


Uncaught TypeError: Cannot read property 'records' of undefined in proxyOData.js:60

Oleg Dolzhansky
14 Mar 2012, 2:16 AM
Yes, I tested the code only with ExtJs 4, not with Sencha Touch. They should have the same code base for data libraries and the code should (ideally) work in both frameworks.

I will test your code and let you know.

necco
14 Mar 2012, 2:48 AM
OK... thanks I will wait for your reply.

By the way... the json received in browser is this one:



{ "d" : { "results" : [ { "__metadata" : { "uri" : "http:\/\/192.168.1.1:7070\/odata\/AGENTI(ADMIN)", "type" : "ODataService.AGENTI" }, "CODAGENT" : "rewrrere", "NUMEAGENT" : "ewrewrew er ewrw", "IDPARTENER" : "1", "PUNCT" : "0", "IDPARINTE" : "-1", "CODAGENT2" : "erewrew", "CNP" : null, "DEFPUNCTLUCRU" : "-5", "CODPALM" : null, "CODCARD_IDENTIFICARE" : null, "DEFGEST" : "999", "DATANASTERII" : null, "BULETINNR" : null, "BULETINEMISDE" : null, "BULETINEMISDATA" : null, "EMAIL" : null, "PASSWD" : "", "CODACTIVITATE" : ".", "SMTPSERVER" : null, "SMTPPORT" : null, "SMTPUSER" : null, "SMTPPASSWORD" : null, "SIR_COMISION" : null, "IDGUID" : " ", "IDGOOGLE" : null, "IDYAHOO" : null, "IDMSN" : null, "IDUSER" : "1", "SITE" : "(2011-06-29 13:47:19) trret", "STERS" : "F", "LOCKPASSWD" : "F", "TOTAL" : "F", "ISADMIN" : "T" }, { "__metadata" : { "uri" : "http:\/\/192.168.1.1:7070\/odata\/AGENTI({IMP})", "type" : "ODataService.AGENTI" }, "CODAGENT" : "{IMP}", "NUMEAGENT" : "Agent Implicit", "IDPARTENER" : "2", "PUNCT" : "0", "IDPARINTE" : "-1", "CODAGENT2" : "{IMP}", "CNP" : "37547559", "DEFPUNCTLUCRU" : "0", "CODPALM" : null, "CODCARD_IDENTIFICARE" : null, "DEFGEST" : "0", "DATANASTERII" : "\/Date(15638400000)\/", "BULETINNR" : null, "BULETINEMISDE" : null, "BULETINEMISDATA" : null, "EMAIL" : null, "PASSWD" : null, "CODACTIVITATE" : ".", "SMTPSERVER" : null, "SMTPPORT" : null, "SMTPUSER" : null, "SMTPPASSWORD" : null, "SIR_COMISION" : null, "IDGUID" : " ", "IDGOOGLE" : null, "IDYAHOO" : null, "IDMSN" : null, "IDUSER" : "15", "SITE" : "(2011-02-09 11:19:46) wretwvtwrt", "STERS" : "F", "LOCKPASSWD" : "T", "TOTAL" : "F", "ISADMIN" : "F" },....]}}

necco
16 Mar 2012, 5:45 AM
Hi Oleg,

Have you succeeded to make odataproxy to work with Sencha Touch 2.0?

Have a nice week-end!

stevo.zilik
5 Apr 2012, 4:58 AM
Hi Oleg,

thanks for this! Any chance you got the filtering working?

Stevo