PDA

View Full Version : Store + Proxy + JSON Reader doesn't work



Mathias.Deshayes
4 Oct 2011, 1:37 AM
Hi,
I'm trying to make a very simple app with a model and a store. The store has a Ajax Proxy and the corresponding URL returns JSON-formatted data.
I try to use a JSON reader to decode this data but I had an error :

Uncaught TypeError: Object #<Object> has no method 'read' ----- Server.js : 138

The Object#<Object> is a simple class with only one attribute which is : "type : 'json'" and has no method. It seems that the definition of my reader didn't work properly.

Here's my code :



Ext.define('MyApp.store.Orders', {
extend : 'Ext.data.Store',
alias : 'widget.orderstore',
model : 'Order',
autoLoad : true,
proxy : {
type : 'ajax',
api : {
read : 'http://localhost:8080/Servlet/Orders',
update : 'http://localhost:8080/Servlet/Orders'
},
reader : {
type : 'json'
}
}
});


The model is :


Ext.define('MyApp.model.Order', {
extend: 'Ext.data.Model',
fields: ['id','status','deadline']
});

Mathias.Deshayes
4 Oct 2011, 2:18 AM
The problem seems to be on the model. The property "model" in my store is "undefined". I change my code to put the proxy in the model :



Ext.define('MyApp.model.Order', {
extend: 'Ext.data.Model',
fields: ['id','status','deadline'],
proxy : {
type : 'ajax',
api : {
read : 'http://localhost:8080/Servlet/Orders',
update : 'http://localhost:8080/Servlet/Orders'
},
reader : {
type : 'json',
root : 'orders'
}
}
});


And my store is now :

Ext.define('MyApp.store.Orders', {
extend : 'Ext.data.Store',
model : 'Order',
autoLoad : true
});


The following error occured :
Uncaught TypeError: Cannot call method 'getProxy' of undefined ---- AbstractStore : 267

The corresponding line is :

me.setProxy(me.proxy || me.model.getProxy());

Don't understand why the store's model is undefined...

MexRus
4 Oct 2011, 2:32 AM
Maybe is because you use a URL?

Limitations on AjaxProxy
AjaxProxy cannot be used to retrieve data from other domains. If your application is running on http://domainA.com it cannot load data from http://domainB.com because browsers have a built-in security policy that prohibits domains talking to each other via AJAX.
If you need to read data from another domain and can't set up a proxy server (some software that runs on your own domain's web server and transparently forwards requests to http://domainB.com, making it look like they actually came from http://domainA.com), you can use Ext.data.proxy.JsonP and a technique known as JSON-P (JSON with Padding), which can help you get around the problem so long as the server on http://domainB.com is set up to support JSON-P responses. See JsonPProxy's introduction docs for more details.

Mathias.Deshayes
4 Oct 2011, 2:39 AM
My application is in the same domain as the Servlet. All is in localhost:8080.
I tried jsonp proxy but the error is the same. My model is always undefined.

I thing the problem is that the model hasn't been registred in the ModelManager, but I don't know why.

Christiand
4 Oct 2011, 3:02 AM
in your store, try to use the full namespace of your model ?



{
..
model : 'MyApp.model.Order'
..
}

mediacept
4 Oct 2011, 3:04 AM
Try to make-it relative to your site (without http://localhost:8080)

api : { read : 'Servlet/Orders', // plus some relative path "../" update : 'Servlet/Orders' // plus some relative path "../" },
As AjaxProxy cannot be used to retrieve data from other domains,
if you put the "http://localhost:8080" it will be considered as not at the same domain, I think.

Mathias.Deshayes
4 Oct 2011, 3:08 AM
Yep I tried, but still the same error.
I use the onClassCreated arg in Ext.define to test if the model is created, and it is not...

It means that my application never reads the Order.js correspoding to the model.

I didn't forget to declare my model in my controller and in app.js :


models : ['Order']

Mathias.Deshayes
4 Oct 2011, 3:14 AM
Thanks but it did not change anything. The Order.js is never read by the application.


Try to make-it relative to your site (without http://localhost:8080)

api : { read : 'Servlet/Orders', // plus some relative path "../" update : 'Servlet/Orders' // plus some relative path "../" },
As AjaxProxy cannot be used to retrieve data from other domains,
if you put the "http://localhost:8080" it will be considered as not at the same domain, I think.

Christiand
4 Oct 2011, 3:16 AM
good, one step closer ? post your app and controller code.

Mathias.Deshayes
4 Oct 2011, 3:22 AM
My app.js :


Ext.application({
name : 'MyApp',
appFolder : 'app',


controllers : ['Orders', 'Users'],
models : ['Order', 'User'],
stores : ['Orders','Users'],
views : ['user.List', 'order.Popup'],


launch : function() {
Ext.create('Ext.container.Viewport', {
layout : 'fit',
items : [{
xtype : 'userlist'
}, {
xtype : 'orderpopup'
}]
});
}
});


My controller :



Ext.define('MyApp.controller.Orders', {
extend : 'Ext.app.Controller',


views : ['order.Popup'],
models : ['Order'],
stores : ['Orders'],


init : function() {
this.control({
...
});
},
//control functions
...


},function() {alert('controler created');});

Christiand
4 Oct 2011, 3:26 AM
in firebug or chromebug do you see your files been loaded ?

you need to use a loader config if your JS files are not all included



Ext.Loader.setConfig({
enabled: true,
disableCaching: true
});

mediacept
4 Oct 2011, 3:33 AM
Try to change your app.js this way:


Ext.application({
name : 'MyApp',
appFolder : 'app',


controllers : ['Orders', 'Users'],
models : ['Order', 'User'],
stores : ['Orders','Users'],
views : ['user.List', 'order.Popup'],

autoCreateViewport: false,


initView = function(resp){eval(resp.responseText);
Ext.create('Ext.container.Viewport', {layout : 'fit',
items : [{xtype : 'userlist'
}, {
xtype : 'orderpopup'
}]
});


}

Mathias.Deshayes
4 Oct 2011, 4:09 AM
Thanks for helping me, unfortunately it doesn't work :-/
I added :


Ext.Loader.setConfig({ enabled : true,
disableCaching : true
});
Ext.application({
...
}


And I also change my application using initView, but the error remains.

Files are not loaded in Chrome

Christiand
4 Oct 2011, 4:17 AM
files are not loaded ? is there any error in the network or console tab ?

Mathias.Deshayes
4 Oct 2011, 4:20 AM
files are not loaded ? is there any error in the network or console tab ?

No error in network, all is "200 OK".
I added :



requires : ['MyApp.model.Order'],
model : 'MyApp.model.Order',


In my controller and it seems to work now.
I have to make few tests before mark this thread as "answered" ;)

Christiand
4 Oct 2011, 4:30 AM
with 4.06, here my working code

app.js


Ext.Loader.setConfig({
enabled: true,
disableCaching: true
});


Ext.application ({

name: 'fdt',
autoCreateViewport: false,
appFolder: '/scripts/app',

controllers: ['Users','Entries'],

launch: function (){
Ext.create('Ext.container.Viewport', {

layout: 'border',
items: [
{
xtype: 'panel',
region: 'west',
title: 'tools',
width: 120
},{
xtype: 'tabpanel',
region: 'center',
items: [
{
xtype: 'entriesgrid'
}
]
}
]
})
}
});


controller


Ext.define('fdt.controller.Entries', {

extend: 'Ext.app.Controller',

views: ['entries.Grid', 'entries.Form', 'entries.Test'],

models: ['ModelEntries', 'ModelTypes'],
stores: ['StoreEntries', 'StoreTypes'],

});


model and store


Ext.define('fdt.model.ModelEntries', {
extend: 'Ext.data.Model',
fields: [
{id: 'ID', name: 'ID', type: 'int'},
{name: 'PRO1', type: 'string'},
{name: 'PRO2', type: 'string'},
{name: 'PRO3', type: 'string'},
{name: 'SEQ', type: 'int'},
{name: 'PDESC', type: 'string'},
{name: 'CRTDATE', type: 'date', dateFormat: 'Ymd'},
{name: 'MODDATE', type: 'date', dateFormat: 'Ymd'},
{name: 'TYPE', type: 'string'},
{name: 'CODE', type: 'string'},
{name: 'DESC', type: 'string'},
{name: 'AMOUNT', type: 'float'},
{name: 'CAT', type: 'string'}
],
proxy: {
type: 'ajax',
format: 'json',


reader: {
type: 'json',
root: 'data',
successProperty: 'success'
},


writer: {
type: 'json',
root: 'data',
writeAllFields: true
},


api: {
read: '/entries/getentries',
destroy: '/entries/delete',
update: '/entries/update',
create: '/entries/new'
}
}
});

Ext.define('fdt.store.StoreEntries', {
extend: 'Ext.data.Store',
model : 'fdt.model.ModelEntries',
autoLoad: true
});


hope that help!

Mathias.Deshayes
4 Oct 2011, 6:35 AM
Ok it works, I have to add the "requires" line in the store (is it a bug?) and the name of the model should be full.