Update record in Sencha Touch Data Store with Ajaxproxy - sencha-touch

I'm developing a simple form with Secha Touch. I have defined a DataStore for my model like this:
App.stores.shopinglists = new Ext.data.Store({
model: 'ShopingList',
autoLoad: false,
proxy: new Ext.data.AjaxProxy({
type: 'ajax',
url: 'http://localhost:2795/ShopingListService/',
reader: {
type: 'json',
root: 'ResultData',
totalProperty: 'Total',
successProperty: 'Success'
},
writer: {
encode: true,
type: 'json'
}
})
});
The view loads fine, and I can see a list of items and edit them. However, when I click the update button, I get the following error:
Uncaught Error: You are using a ServerProxy but have not supplied it with a url.
What I am missing here? The proxy has the url defined, but when update is invoked, it's undefined.
Edit: The button just call a controller action.
onSaveAction: function () {
var model = this.getRecord();
Ext.dispatch({
controller: 'ShopingLists',
action: (model.phantom ? 'save' : 'update'),
data: this.getValues(),
record: model,
form: this
});
},
The code executed by the controller is this:
update: function (params) {
debugger;
var tmpshopingList = new App.models.ShopingList(params.data);
var errors = tmpshopingList.validate();
if (errors.isValid()) {
params.record.set(params.data);
params.record.save();
this.index();
} else {
params.form.showErrors(errors);
}
},

I think I know what is happening: The model knows it has a server proxy, but all of the configurations are not being copied over. Perhaps this is a bug with Sencha Touch 1.x.
Try putting the proxy configuration into your model, not your store.

Related

Add a auto initialize function inside a Sencha Touch model to manipulate model's data

When I load a store, due to the API structure, I get a json object inside my model:
Ext.define('TestApp.model.SecretKeyModel', {
extend: 'Ext.data.Model',
config:{
identifier: {
type: 'uuid'
},
fields: [
{ name:'theRecord', type:'json' }
]
},
extractToken: function() {
var record = this;
var token = record.initSession.token;
console.log('token: ' + token);
}
});
I need to extract the token from that json object.
For that, i think I should write a function right there, inside the model.
How can I call it, when the store loads, to manipulate the data and extract the token?
I faced a similar situation 1 hour ago, i needed to edit data during loading or immidiatly after. I ended with this solution:
Ext.define('TestApp.store.MyStore', {
extend: 'Ext.data.Store',
requires: ['TestApp.model.SecretKeyModel'],
config :{
model: 'TestApp.model.SecretKeyModel',
proxy: {
type: 'ajax',
url: TestApp.utils.GlobalVariables.getServerUrl(),
reader: {
type: 'json',
rootProperty: ''
}
},
listeners: {
refresh: function(store, data, eOpts) {
store.each(function (item, index, length) {
item.extractToken(); // call this on every record loaded in the store
});
}
}
}
});

Sencha Touch:How to capture Status code Returned by Server

I am developing a Sencha touch application using SAP 'Odata' proxy.
In my store I am calling the URL for READ operation
http:///sap/opu/odata/sap/TECHHELP/Tickets
I am loading the store manually in the controller using the following code
var ticketStore = Ext.getStore("Tickets");
var proxy=ticketStore.getProxy();
ticketStore.load(function(records, operation, success) {
if(success){
console.log('loaded records');
}
else{
console.log('loading failed');
}
}, this);
When the application is executed in browser, in network tab I can see the format
Status Code:401 Unauthorized
Now when the URL is executed, I want to capture the exact status Code and the Message in the application.
I want to capture the possible error conditions by checking the status codes returned from server for Eg: 500,401,200,204
How Can I do this?
Regards,
P
this was helpful for me.
new Ext.data.Store({
model: "Your Model",
proxy:{
type: 'ajax',
url: "SomeURL",
reader: new Ext.data.JsonReader({
type: 'json',
root: 'SOME ROOT'
}),
listeners: {
exception:function (proxy, response,operation) {
console.log(response.status);
console.log(response.responseText);
}
}
}
})
May be this will helpful for you.

Why success callback is not called in extjs form submission?

I'm trying to upload a file using Ext JS forms and in case of success or failure, show appropriate messages. But I'm not able to get the desired result. I'm not able to make success or failure callbacks work in form.submit action.
What I've done till now is:
Creating a form with this script:
new Ext.FormPanel({
fileUpload: true,
frame: true,
url: '/profiler/certificate/update',
success: function() {
console.log(arguments);
},
failure: function() {
console.log(arguments);
}
}).getForm().submit()
​/*
The response Content-Type is text/html (with charcode=utf8);
The response JSON is: { "success": true }
*/​​
Setting the response Content-Type to text/html based on this answer.
Sending an appropriate JSON result back, based on Ext JS docs. The response captured via Fiddler is:
{"success":false}
or
{"success":true}
I even set the response Content-Type to application/json. But still no success.
I've read links like this and this, but none of them helped. Please note that I also tried another script which creates a form, with an upload field in it, and a save button, and I submitted the form in the handler of the save button. But still no callback is fired.
Here's a working example - Javascript code:
Ext.onReady(function () {
Ext.define('ImagePanel', {
extend: 'Ext.form.Panel',
fileUpload: true,
title: 'Upload Panel',
width: 300,
height: 100,
onUpload: function () {
this.getForm().submit({
url: 'upload.php',
scope: this,
success: function (formPanel, action) {
var data = Ext.decode(action.response.responseText);
alert("Success: " + data.msg);
},
failure: function (formPanel, action) {
var data = Ext.decode(action.response.responseText);
alert("Failure: " + data.msg);
}
});
},
initComponent: function () {
var config = {
items: [
{
xtype: 'fileuploadfield',
buttonText: 'Upload',
name: 'uploadedFile',
listeners: {
'change': {
scope: this,
fn: function (field, e) {
this.onUpload();
}
}
}
}
]
};
Ext.apply(this, Ext.apply(this.initialConfig, config));
this.callParent(arguments);
}
});
var panel = Ext.create('ImagePanel', {
renderTo: Ext.getBody()
});
});
And PHP code:
<?php
if (isset($_FILES)) {
$temp_file_name = $_FILES['uploadedFile']['tmp_name'];
$original_file_name = $_FILES['uploadedFile']['name'];
echo '{"success": true, "msg": "'.$original_file_name.'"}';
} else {
echo '{"success": false, "msg": "No Files"}';
}
I have been struggling with this for quite some time now as well. Here's my code:
Ext.getCmp('media-upload-form').getForm().doAction('submit', {
url: './services/recordmedia/upload',
method: 'post',
waitMsg: 'Please wait...',
params: {
entityId: this.entityId,
},
failure: function(form, action){
alert(_('Error uploading file'));
this.fireEvent('file-upload');
this.close();
},
success: function(form, action){
this.fireEvent('file-upload');
this.close();
},
scope: this
})
The response was always wrapped in <pre> tags by the browser, what caused the Extj lib not to call the callbacks. To fix this:
make sure your server returns the correct json: {"success":true}
make sure that the content-type is set to text/html
Actually, this is well covered by docs for Ext.form.Panel and Ext.form.Basic. The problem with your code not working is that there are no config options "success", "failure" for the form panel. You should put them in the config object passed to the submit action. So your code should look like:
new Ext.FormPanel({
fileUpload: true,
frame: true
}).getForm().submit({
url: '/profiler/certificate/update',
success: function() {
console.log(arguments);
},
failure: function() {
console.log(arguments);
}
});
Note the difference: In Ext 4, there is a form component (Ext.form.Panel) which is basically a view component concerned with how you form looks, and then there is the underlying form class (e.g. Ext.form.Basic) concerned with the functionality. Form submissions are handled by Ext.form.Basic (or whatever returned by your form.getForm()).

MVC JSONP TreeStore

I'm starting coding with Sencha Touch and I would like to do the same thing as below, but at distance:
MyApp.search = new Ext.data.TreeStore({
model: 'ListItemSearch',
proxy: {
type: 'ajax',
url: 'search.json',
reader: {
type: 'tree',
root: 'items'
}
}
});
It's working fine, but I'd like to make it at distance with JSONP like this:
MyApp.search = new Ext.data.TreeStore({
model: 'ListItemSearch',
proxy: {
type: 'ajax',
url: 'http://www.test.com/search.json',
reader: {
type: 'tree',
root: 'items'
}
}
});
I don't know how to code this, and the examples that I tried didn't work.
How can I do this?
if your JavaScript code isn't running at the same domain as your ajax request (test.com) then you will have security issues. Check to make sure the proxy type 'ajax' is using JSONP
I think you have to use the sencha JSONP library to do this.

Read ExtJS message from ajax store

I have an ExtJS store with an ajax proxy and json reader:
Ext.create('Ext.data.Store', {
proxy: {
type: 'ajax',
url: '...',
reader: {
type: 'json',
root: 'data',
totalProperty: 'totalCount',
messageProperty: 'message',
successProperty: 'success'
},
...
This is what I get from the server:
data: [...]
message: "I want to read this string after the store is loaded"
success: true
totalCount: x
Now I want to access the 'message' when the store is loaded - where do I get it? I looked a lot but I can't find a place to hook in? The only listener in the proxy is exception, that doesn't really help me.
use store load event:
Ext.create('Ext.data.Store', {
listeners: {
'load': function(store, records, successful, operation) {
alert(operation.resultSet.message);
}
},
proxy: {
// ...
UPDATE
It appears that documentation for load event is wrong. The correct list of arguments is (store, records, successful) (no operation argument). Therefore the solution above wouldn't work.
However there is reader's rawData property which can help:
Ext.create('Ext.data.Store', {
listeners: {
'load': function(store, records, successful) {
alert(store.getProxy().getReader().rawData.message);
}
},
proxy: {
// ...
My answer applies to ExtJs 4.1.x. I spent some time reading the code and it seems that one way to do this is to provide a callback in the store beforeload event instead of handling the load event. The callback is passed the operation object which will contain the original request parameters and in case of success it will contain the response object and the data (parsed) under the resultSet property.
In other case:
myStore.load({
callback : function(object, response, success) {
// on error response: success = false
if(!success) {
// i don't remember de correct path to get "message" or "responseText"
console.log(response.response.responseText);
} else {
...
}
});
Cya!
I get the message in the following way although I load manually and do not use events here:
var initData = Ext.create('My.data.SomeAjaxStore');
initData.load(function(records, operation, success) {
if (!success || operation.hasException()) {
// Here is your message from server
// In case of HTTP error you get:
// {
// status: 404,
// statusText: "Not Found"
// }
var error = operation.getError();
Ext.log({msg:[Ext.getClassName(me), ": Command failure: ", error].join(""), level:"error"});
}