PDA

View Full Version : params with ScriptTagProxy or HttpProxy



devil1591
28 Nov 2007, 8:28 AM
Hello,
I tried to send params when creating a ScriptTagProxy or HttpProxy, just like I'm doing in a Ext.Ajax.request...I there something I missed ?



new Ext.data.ScriptTagProxy({
url: 'foo.php',
method: 'POST', // or GET
params: {bar: 'toto', id: 51}
})

Is this correct ?
Thanks in advance :)

CreamyWhiteThighs
28 Nov 2007, 2:28 PM
I tracked down what I think is a bug in Ext.data.HttpProxy. It looks like the parameters we pass, like this:

proxy: new Ext.data.HttpProxy({
url: 'http://localhost:3000/xml/daydetail',
params: { id: row_id }
})

are removed during HttpProxy.load. In .load, the params passed as part of the .load() function are evaluated and if no params are passed, the code in .load creates an empty object called params:

11148 load : function(params, reader, callback, scope, arg){
...
11150 var o = {
11151 params : params || {},

Down further in the code, the params that we passed as part of the HttpProxy object (this.conn) are copied in the the Var 'o' listed above using Ext.applyIf():

11161 if(this.useAjax){
11162 Ext.applyIf(o, this.conn);

'this.conn' has two memers, the URL we want and the params we want. The params are stored under 'this.conn.params' while the URL is 'this.conn.url'. If we look at the code for Ext.applyIf(), I think we see that while it copies objects, it doesn't copy over existing members:

applyIf:
function(o,c){
if(o&&c){
for(var p in c){
if(typeof o[p]=="undefined"){
o[p]=c[p]
}
}
}
return o
}

So, after line 11162 executes, we have a Var 'o' with a URL from this.conn, but since the 'params' member was created up in line 11151 applyIf won't overwrite it. Var 'o' is then used to request the data:

11166 this.activeRequest = Ext.Ajax.request(o);

Which, of course, has no params but has a valid URL. So the URL is requested as a GET with no params.

devnull
28 Nov 2007, 3:03 PM
the idea behind 'applyIf' is that it copies any member of c to o if it doesnt already exist in o.
Since no params are supplied to the load method, params gets set to an empty object. since an empty object does not resolve as 'undefined', the new empty object replaces the existing params in applyIf.
the problem is not specifically in that function as it is used successfully basically in ever single Ext element.

what it comes down to is that you should use 'baseParams' in the constructor, and 'params' when calling the load method. (as needed of course)

CreamyWhiteThighs
28 Nov 2007, 3:31 PM
@devnull. I wasn't saying that applyIF was buggy. I was saying that the way applyIf is used in HttpProxy makes no sense and is counter intuitive because it wipes passed parameters silently.

If params are specified in the HttpProxy constructor call they should override (or complement) any parameters that exist as base parameters. The code would be better written to use the passed params if baseParams are not specified and if baseParams exist, then complement them with the passed params. This is more flexible and it makes more sense when you read the code. Otherwise, the way it works today, you can pass seemingly meaningful parameters to the HttpProxy object but they are SILENTLY ignored. That's no good.

CreamyWhiteThighs
28 Nov 2007, 4:09 PM
Also, now that I look at it, I don't see where baseParams even comes into this. Looking at the documentation, it would appear that baseParams are a part of Store not a part of DataProxy. With that said, I take back my previous post and call this a bug.

tryanDLS
28 Nov 2007, 5:21 PM
params is not valid config option for the proxy. If you're passing a config object rather than a Connection, the valid config properties are those of Connection. You could pass them as extraParams.

CreamyWhiteThighs
28 Nov 2007, 8:51 PM
@tim - You're right, of course, the 'params' member we're dealing with is in Connection. But this still doesn't explain why params defined in a config object, and passed to HttpProxy's constructor, are ignored in HttpProxy.load().

The documentation for the constructor of HttpProxy:

HttpProxy( Object conn )
Parameters:

* conn : Object
Connection config options to add to each request (e.g. {url: 'foo.php'}) or an Ext.data.Connection object. If a Connection config is passed, the singleton Ext.Ajax object will be used to make the request.

An example from the doc for Ext.Ajax (clearly showing the use of params):

// Basic request
Ext.Ajax.request({
url: 'foo.php',
success: someFn,
failure: otherFn,
headers: {
'my-header': 'foo'
},
params: { foo: 'bar' }
});

And the doc for Ext.Ajax.request:
request( [Object options] ) : Number
Sends an HTTP request to a remote server. Important: Ajax server requests are asynchronous, and this call will return...
Sends an HTTP request to a remote server.

Important: Ajax server requests are asynchronous, and this call will return before the response has been recieved. Process any returned data in a callback function.
Parameters:

* options : Object
An object which may contain the following properties:
o url : String (Optional)
The URL to which to send the request. Defaults to configured URL
o params : Object/String/Function (Optional)
An object containing properties which are used as parameters to the request, a url encoded string or a function to call to get either.
...

My code that refuses to pass params to the server:

proxy: new Ext.data.HttpProxy({
url: 'http://localhost:3000/xml/daydetail',
params: { id: row_id }
})

So, since the examples are assigning 'params' a value in the config object for the Ext.Ajax.request() call, why does my code have it's parameters ignored? I swear, after stepping through the code for an hour, I'm pretty sure the intent was not to ignore the values of this.conn.params because Ext.Ajax.request() is expecting them. This is the Ajax call in HttpProxy.load():



11161 if(this.useAjax){
11162 Ext.applyIf(o, this.conn);
11163 if(this.activeRequest){
11164 Ext.Ajax.abort(this.activeRequest);
11165 }
11166 this.activeRequest = Ext.Ajax.request(o);


Can someone offer an example using 'params' in the config object for HttpProxy's constructor that works (as the Ext.Ajax.request example above)? I don't know how it could work because line 11162 will remove them before line 11166.

Or is this a bug? :)

Animal
29 Nov 2007, 4:01 AM
That's just the way HttpProxy uses the Ajax singleton.

It sets up the options object containing the parameters passed into load.

Then it applies your settings using applyIf so as not to override the stuff it has set up to make itself work.

Why are you using HttpProxy directly? Usually, you use it in conjunction with a Store to which yuo can add baseParams.

CreamyWhiteThighs
1 Dec 2007, 5:42 PM
@animal - I was using a code fragment for purposes of discussion. In my code this is part of a reader for a data store. I understand what you're saying, but I'm still not understanding why HttpProxy ignoring parameters passed as part of the constructor would be considered proper behavior. If you step through the code, the params doesn't even exist until created in .load() if you specify the params in the constructor. So by creating a blank params member and then *attempting* to use applyIf() to setup the Ajax call, the params passed in this.conn.params are ignored. Which I still contend doesn't make sense. Why not check the value of this.conn.params and if not null combine them with any params passed as a part of .load()?

devnull
3 Dec 2007, 11:22 AM
The problem is pretty clear to me, and is well explained by this:
params is not valid config option for the proxy
so it does what anything would do with an unsupported config option; ignores it.
what part of this doesnt make sense?