PDA

View Full Version : Sencha Touch JSON Writer Issue



cassebn
6 Dec 2010, 5:38 PM
With the following store I notice the writer isn't sending over a POST param of data but instead sending it in a "Request Payload". I haven't ever seen this before and was curious on how to handle it in my PHP file. With EXTJS I can just look for a POST param of "data" and iterate through the object.

How do you send a "data" object in a POST param with Sencha Touch but still utilize the stores writer functionality?

Here is what shows up in my Resource pane of developer tools in Safari:

Request Payload: {"data":[{"id":1,"username":"cassebn","fname":"foo","lname":"bar","password":"pwd","last_login":"2010-12-05 13:35:00"}]}


Ext.regStore("UserStore", {
model: 'UserModel',
sorters: 'lname',
getGroupString: function(record){
return record.get('username')[0];
},
proxy: {
type: 'ajax',
url: 'users.php',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
root: 'data'
}
},
autoLoad: true
});

mrsunshine
7 Dec 2010, 12:53 AM
Try the rest proxy instead http://dev.sencha.com/deploy/touch/docs/?class=Ext.data.RestProxy
the rest proxy sends a POST request

jochem kuun
7 Mar 2011, 7:03 AM
I've got the same problem. I've found a temporary solution by using the following code to read the submitted data. I don't really know exactly why it works this way, but here's the code:


$raw = '';
$httpContent = fopen('php://input', 'r');
while ($kb = fread($httpContent, 1024)) {
$raw .= $kb;
}
fclose($httpContent);
$params = json_decode(stripslashes($raw));
print_r($params); //should contains the passed data decoded as array.

I'm using the following (test)model:


/*global Ext */

Ext.regModel('LessonReview', {
idProperty: 'id',
fields: [{
name: 'id',
type: 'int'
}, {
name: 'score',
type: 'int'
}, {
name: 'date_added',
type: 'date'
}, {
name: 'date_updated',
type: 'date'
}],

proxy: {
type: 'ajax',
url : '/poc/api/lessonreviews.php'
reader: {
type: 'json'
}
}
});

When a user presses a save button, i'd like to save the model to the database and perform some other functions like changing the view:


{
text: 'Opslaan',
ui: 'confirm',
scope: this,
handler: function(){
var data = this.getValues(),
//store = Ext.getStore('LessonReviews');

var review = Ext.ModelMgr.create(data, 'LessonReview');
review.save();

//store.sync(); dont know if this is needed???
Ext.getCmp('lesson-reviews').setActiveItem(0);
}
}

I'm using the Sencha MVC framework so the code inside the handler would normaly be placed inside an controller action.

When using the code above, a print_r($_POST) on the page '/poc/api/lessonreviews.php' results in an empty array. As the TS already stated the data IS available inside Request Payload.

I've tried changing the proxy type to 'rest' but this has no effect.
Are there other (easier) ways to get the data?

mikeycgto
14 Apr 2011, 6:45 AM
has anyone figured out how to make the POST body be URL encoded?

Bunchofstring
22 Sep 2011, 5:53 PM
I am having this issue as well with Sencha Touch 1.1. Can someone please help? This is my second try with Sencha Touch after I gave up in late-2010 because of issues with server requests (much like this). Not everyone can just re-purpose their backend to handle JSON....

Bunchofstring
22 Sep 2011, 7:03 PM
Okay... this may be ugly and goofy, but it works for me. The code below allows my server to understand the web app's command to create a new user on the backend. The response isn't understood yet, but the user account is created successfully. I guess the code could go into a store too, but that's for *you* to test.

In Sencha Touch 1.1, it urlencodes the form data/request payload (default is JSON encoded). For those of us with less than flexible backends (i.e. those that don't understand JSON or XML), it might be helpful.



Ext.regModel('Player', {
fields: ['name','mail'],
proxy: {
type: 'rest',
writer:{
type:'json',
writeRecords:function(request,data){
Ext.apply(data[0],request.params);
request.jsonData=Ext.urlEncode(data[0]);
return request;
},
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
url : 'my_service_endpoint_url',
extraParams:{
apikey:'sent_with_every_request',
},
}
});
var player = Ext.ModelMgr.create({name: 'Test', mail: 'test@test.com'}, 'Player');
player.save();

Please feel free to improve the code, but remember to share with the community ;o)

tjhoeft
18 Jul 2013, 5:06 AM
Hello everyone,
I am new to Sencha Touch. This is very interesting. I am playing with my first app to test JSON IO with a local file. I’m having the same issues as described on the forums receiving the following warning (and no data being written to the file on my “create” requests). I am currently using Sencha Touch 2.2.1, the sencha web server (Sencha Cmd v3.1.2.342), Google chrome and the Ripple plugin for testing.



[WARN][Ext.data.Operation#process] Unable to match the record that came back from the server.


Can you please help?


Thank you,
TJ







/****************************************************
VIEW: MAIN
****************************************************/
Ext.define('MyApp.view.CrudMain', {
extend: 'Ext.navigation.View'
,xtype: 'crudmainpanel'

,requires: [
'MyApp.view.CrudList'
,'MyApp.view.CrudToolbar'
]

,config: {
items:[
{
xtype: 'crudlist'
,title: 'JSON CRUD Ops'
}
,{
xtype: 'crudtoolbar'
,docked: 'bottom'
}
]
}
});




/****************************************************
VIEW: LIST
****************************************************/
Ext.define('MyApp.view.CrudList', {
extend: 'Ext.List'
,xtype: 'crudlist'


,requires: [
'MyApp.store.CrudStore'
]

,config:{
itemTpl: '{message}'
,store: 'crudstoreid'
}
});


/****************************************************
VIEW: TOOLBAR
****************************************************/
Ext.define('MyApp.view.CrudToolbar', {
extend: 'Ext.Toolbar'
,xtype: 'crudtoolbar'

,config: {
defaults:{
ui: 'plain'
}

,docked: 'bottom'
,layout: {
type: 'hbox'
,align: 'middle'
}

,items: [
{
xtype: 'button'
,text: 'Create'
,action: 'create'
}
,{
xtype: 'button'
,text: 'Read'
,action: 'read'
}
,{
xtype: 'button'
,text: 'Update'
,action: 'update'
}
,{
xtype: 'button'
,text: 'Delete'
,action: 'delete'
}
]
}
});






/****************************************************
MODEL
****************************************************/
Ext.define('MyApp.model.CrudModel', {
extend: 'Ext.data.Model'


,config:{
identifier: {
type: 'sequential'
}
,fields: [
{
name: 'id'
},
{
name: 'message'
,type: 'string'
}
]
}
});




/****************************************************
STORE
****************************************************/
Ext.define('MyApp.store.CrudStore', {
extend: 'Ext.data.Store'
,xtype: 'crudstore'


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

,config:{
model: 'MyApp.model.CrudModel'
,storeId : 'crudstoreid'
,autoLoad: true
,autoSync: true

//Pull Store data from a local JSON file to populate
,proxy: {
type: 'ajax'
,url: 'app/data/CrudData.json'

,reader: {
type: 'json',
idProperty: 'id',
rootProperty: 'Messages'
}
,writer: {
type: 'json',
rootProperty: 'Messages'
}
}
}
});




/****************************************************
CONTROLLER
****************************************************/
Ext.define('MyApp.controller.CrudController', {
extend: 'Ext.app.Controller'

,requires: [
'MyApp.view.CrudToolbar'
,'MyApp.store.CrudStore'
]

,config: {
refs: {
/*Query for event firers*/
createBtn: 'crudtoolbar button[action=create]'
,readBtn: 'crudtoolbar button[action=read]'
,updateBtn: 'crudtoolbar button[action=update]'
,deleteBtn: 'crudtoolbar button[action=delete]'
}

,stores: ['MyApp.store.CrudStore']
,models: ['MyApp.model.CrudModel']


/*
The goal of this controller is largely to respond to events.
*/
,control: {
createBtn: {
tap: 'createJsonEntry'
}
,readBtn: {
tap: 'clicked'
}
,updateBtn: {
tap: 'clicked'
}
,deleteBtn: {
tap: 'clicked'
}
}
}


,createJsonEntry: function(e){
var currentdate = new Date();
var datetime = "Time: " + currentdate.getDate() + "/"
+ (currentdate.getMonth()+1) + "/"
+ currentdate.getFullYear() + " @ "
+ currentdate.getHours() + ":"
+ currentdate.getMinutes() + ":"
+ currentdate.getSeconds();

var myStore = Ext.getStore('crudstoreid');
myStore.add({message: datetime});

//Do I have to have this here?
myStore.sync();
}


,clicked: function(e){
Ext.Msg.alert('Clicked: ' + e.getText());
}
});






/****************************************************
JSON DATA
url: 'app/data/CrudData.json'
****************************************************/
{
"Messages" : [
{id: 1, message: 'Trying to figure out'}
,{id: 2, message: 'how to add data to JSON'}
]
}

vote539
20 Jul 2013, 7:55 PM
Even in the newest version of Sencha Touch, there remain only the two proxy writers: JSON and XML. However, traditional URL-Encoded POST parameters remain the most widely supported on the client side. Here is a short gist that implements a UrlEncodeWriter:

https://gist.github.com/vote539/6047372

To use it in your project, first include the file (prior to app.js; a JavaScript Resource in Architect will do), then wherever you had this:


proxy: {
type: 'rest',
url: 'example.php',
reader: {
type: 'json'
},
writer: {
type: 'json'
}
}

use writer type: 'urlencode' instead, like this:


proxy: {
type: 'rest',
url: 'example.php',
reader: {
type: 'json'
},
writer: {
type: 'urlencode'
}
}