ExtJS: Rest Proxy Post Data Failure - rest

Hy,
I've a Problem by sending data via ExtJs Rest Proxy. When I POST Data I get the Exception
in Chrome: Uncaught TypeError: Cannot read property 'clientIdProperty' of undefined
in Firefox: TypeError: clientRecords[0] is undefined
My Store
Ext.define('Test.store.Test', {
extend: 'Ext.data.Store',
requires: [
'Test.model.test',
'Ext.data.proxy.Rest',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'Test',
model: 'Test.model.test',
proxy: {
type: 'rest',
url: '/resources/php/test.php',
reader: {
type: 'json'
}
}
}, cfg)]);
}
My Model
Ext.define('Test.model.test', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name: 'Test'
}
]
Is there a standard answer from Server?
I hope some one can Help me
Thx for Help

In your reader config, provide a 'root' property.
In ext 4.x it'll be like
reader: {
type: 'json',
root: 'root'
}
And in Ext 5.x, it'll be
reader: {
type: 'json',
rootProperty: 'root'
}
Here's what API doc says -
rootProperty : String The name of the property which contains the data
items corresponding to the Model(s) for which this Reader is
configured. For JSON reader it's a property name (or a dot-separated
list of property names if the root is nested). For XML reader it's a
CSS selector. For Array reader the root is not applicable since the
data is assumed to be a single-level array of arrays.
By default the natural root of the data will be used: the root JSON
array, the root XML element, or the array.
The data packet value for this property should be an empty array to
clear the data or show no data.
Defaults to: ''
For example, if the JSON response from the server is
{
"data": {
"Test": "TEST"
},
"someOtherField": "Some Value"
}
then, your rootProperty/ root will become -
rootProperty: 'data'
- Since data corresponds to your model

Related

importing schema from file causes ReferenceError: Cannot access 'MySchema' before initialization

I have a schema that I export from a file
// Vendor.ts
export { ShortVendorSchema };
const ShortVendorSchema = new Schema<TShortVendor>({
defaultVendor: Boolean,
companyName: String,
vendorId: { type: Schema.Types.ObjectId, ref: 'Vendor' },
});
and import it to another schema
// Order.ts
import { ShortVendorSchema } from './Vendor';
const OrderSchema = new Schema<TOrderSchema>(
{
status: {
type: String,
enum: Object.keys(ORDER_STATUS),
default: 'NEW',
},
vendor: ShortVendorSchema,
},
{ timestamps: true }
);
Whenever I'm trying to access Order model I get error error - ReferenceError: Cannot access 'ShortVendorSchema' before initialization
I have an idea why it happens, something about api routes living in isolation, but I don't know how to solve it without duplicating ShortVendorSchema in all files where it's used.
upd: moved all model exports into a single file, now I'm getting error error - TypeError: Cannot read properties of undefined (reading 'ShortVendorSchema')
Any ideas?
The error occurs because of circular dependency.
I was importing ShortVendorSchema to Order.ts file and OrderSchema to Vendor.ts file.
The solution is to move ShortVendorSchema to a separate file that doesn't have any imports.

How to access complex REST resources with ExtJS 5

I am using ExtJS 5 and I want to access complex REST resources as discussed in this similar thread using ExtJS 4.
The REST service that I am accessing exposes these resources:
GET /rest/clients - it returns a list of clients
GET /rest/users - it returns a list of all users
GET /rest/clients/{clientId}/users - it returns a list of users from the specified client.
I have these models:
Ext.define('App.model.Base', {
extend: 'Ext.data.Model',
schema: {
namespace: 'App.model'
}
});
Ext.define('App.model.Client', {
extend: 'App.model.Base',
fields: [{
name: 'name',
type: 'string'
}],
proxy: {
url: 'rest/clients',
type: 'rest'
}
});
Ext.define('App.model.User', {
extend: 'App.model.Base',
fields: [{
name: 'name',
type: 'string'
},{
name: 'clientId',
reference: 'Client'
}],
proxy: {
url: 'rest/users',
type: 'rest'
}
});
I did this:
var client = App.model.Client.load(2);
var users = client.users().load();
And it sent, respectively:
//GET rest/clients/2
//GET rest/users?filter:[{"property":"personId","value":"Person-1","exactMatch":true}]
Questions:
Is there any way that I can send my request to "GET rest/clients/2/users" without updating the user proxy url manually with its clientId?
How can I send above request without losing the original url defined in App.model.User, "rest/users"
I think this essentially the same as this question:
Accessing complex REST resources with Ext JS
I don't think much has changed since it was first asked.

Ext.Direct File Upload - Form submit of type application/json

I am trying to upload a file through a form submit using Ext.Direct, however Ext.direct is sending my request as type 'application/json' instead of 'multipart/form-data'
Here is my form.
{
xtype: 'form',
api: {
submit: 'App.api.RemoteModel.Site_Supplicant_readCSV'
},
items: [
{
xtype: 'filefield',
buttonOnly: false,
allowBlank: true,
buttonText: 'Import CSV'
}
],
buttons:
[
{
text: 'Upload',
handler: function(){
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
waitMsg: 'Uploading...',
success: function(form, action){
console.log(action.result);
}
});
}
}
}
]
},
On the HTTP request, it checks to see if the request options is a form upload.
if (me.isFormUpload(options)) {
which arrives here
isFormUpload: function(options) {
var form = this.getForm(options);
if (form) {
return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype')));
}
return false;
},
getForm: function(options) {
var form = options.form || null;
if (form) {
form = Ext.getDom(form);
}
return form;
},
However, options looks like this
{
callback: function (options, success, response) {
jsonData: Object
action: "RemoteModel"
data: Array[1]
0: form
length: 1
__proto__: Array[0]
method: "Site_Supplicant_readCSV"
tid: 36
type: "rpc"
__proto__: Object
scope: constructor
timeout: undefined
transaction: constructor
}
And there is no direct form config, but it exists in jsonData.data[0]. So it doesn't set it as type multipart/form-data and it gets sent off as type application/json.
What am I doing wrong? Why isn't the form getting submitted properly?
Edit - I am seeing a lot of discussion about a 'formHandler' config for Ext.Direct? I am being led to assume this config could solve my issue. However I don't know where this should exist. I'll update my post if I can find the solution.
Solution - Simply adding /formHandler/ to the end of the params set the flag and solved my issue. Baffled.
Supplicant.prototype.readCSV = function(params,callback, request, response, sessionID/*formHandler*/)
{
var files = request.files;
console.log(files);
};
The method that handles file upload requests should be marked as formHandler in the
Ext.Direct API provided by the server side.
EDIT: You are using App.api.RemoteModel.Site_Supplicant_readCSV method to upload files; this method needs to be a formHandler.
I'm not very familiar with Node.js stack but looking at this example suggests that you may need to add /*formHandler*/ descriptor to the function's declaration on the server side.

Cannot save a document in Mongoose - Validator required failed for path error

Following is my schema:
var userSchema = new Schema({
username: {
type: String,
required: true
},
password: {
type: String,
required: false
}
});
Now, when I attempt to save a document of the above schema, I get the following error:
{ message: 'Validation failed',
name: 'ValidationError',
errors:
{ username:
{ message: 'Validator "required" failed for path username',
name: 'ValidatorError',
path: 'username',
type: 'required' } } }
The above is the error object returned by mongoose upon save. I searched for this error but could not understand what is wrong. The document that I am trying to save is as follows:
{
username: "foo"
password: "bar"
}
Any idea what this means? I searched the mongoose docs too but could not find anything under the validation section.
First, you are missing a comma (,) after foo.
Now, is { username: "foo", password: "bar" } JSON sent via http, our an actual object in your server-side code ?
If it is, try to console.log(youVariable.username) and see if it shows undefined or the value foo. If you see undefined, then your object is not parsed properly.
You can make sure that whom ever is sending the POST request is sending a "application/json" in the header, you could be receiving something else, thus your JSON isn't parsed to a valid javascript object.

Custom proxies on Stores and Models seems inconsistent (and does not work on Models)

Am using Extjs 4, and have created a custom Rest Proxy to handle communication with my Zend backend api.
(See post http://techfrere.blogspot.com/2011/08/linking-extjs4-to-zend-using-rest.html)
When using a Store to handle communication, I was using Ext.require to load the proxy, and then referenced the proxy on the type field and all was good and it loaded my data: as per:
Ext.require('App.utils.ZendRest');
...
proxy : {
type : 'zest', // My custom proxy alias
url : '/admin/user'
...
}
I then decided to try to use the proxy directly on a model... and no luck. The above logic does not work.
Problems
1. When referencing zest, it does not find the previously loaded ZendRest class (aliased to proxy.zest)
2. It tries to load the missing class from App.proxy.zest (which did not exist.)
So I tried moving my class to this location and renaming to what it seemed to want. No luck.
It loads the class, but still does not initialize the app... I get no errors anywhere so v difficult to figure out where the problem is after this...
For now it seems I will have to revert to using my Zend Rest proxy always via the Store.
Question is... has anyone else seen the behavior? Is it a bug, or am I missing something?
Thanks...
Using your proxy definition, I've managed to make it work.
I am not sure why it doesn't work for you. I have only moved ZendRest to Prj.proxy namespace and added requires: ['Prj.proxy.ZendRest'] to the model.
Code:
// controller/Primary.js
Ext.define('Prj.controller.Primary', {
extend: 'Ext.app.Controller',
stores: ['Articles'],
models: ['Article'],
views: ['article.Grid']
});
// model/Article.js
Ext.define('Prj.model.Article', {
extend: 'Ext.data.Model',
fields: [
'title', 'author', {
name: 'pubDate',
type: 'date'
}, 'link', 'description', 'content'
],
requires: ['Prj.proxy.ZendRest'],
proxy: {
type: 'zest',
url: 'feed-proxy.php'
}
});
// store/Articles.js
Ext.define('Prj.store.Articles', {
extend: 'Ext.data.Store',
autoLoad: true,
model: 'Prj.model.Article'
});
// proxy/ZendRest.js
Ext.define('Prj.proxy.ZendRest', {
extend: 'Ext.data.proxy.Ajax',
alias : 'proxy.zest',
appendId: true,
batchActions: false,
buildUrl: function(request) {
var me = this,
operation = request.operation,
records = operation.records || [],
record = records[0],
format = me.format,
reqParams = request.params,
url = me.getUrl(request),
id = record ? record.getId() : operation.id;
if (me.appendId && id) {
if (!url.match(/\/$/)) {
url += '/';
}
url += 'id/' + id;
}
if (format) {
reqParams['format'] = format;
}
/* <for example purpose> */
//request.url = url;
/* </for example purpose> */
return me.callParent(arguments);
}
}, function() {
Ext.apply(this.prototype, {
actionMethods: {
create : 'POST',
read : 'GET',
update : 'PUT',
destroy: 'DELETE'
},
/* <for example purpose> */
reader: {
type: 'xml',
record: 'item'
}
/* </for example purpose> */
});
});
Here is working sample, and here zipped code.