Hi, > If the function "show_message" is in " new Ajax.Request()" , the result > corresponds to the Request. > But if the function "show_message" is outside "new Ajax.Request()" then the > result corresponds to the previous Request. > I don't understand why ?
It's because Ajax requests are *asynchronous* (by default). Let's take an example of a request that returns a plain text response which will be "SUCCESS:data" on success, or "ERROR" on error: function foo(url) { var data; new Ajax.Request(url, { onSuccess: function(response) { if (response.responseText.substring(0, 8) === "SUCCESS:") { data = response.responseText.substring(8); } else { data = "(could not get data)"; } } }); alert(data); // <== WRONG, always alerts 'undefined' } What happens when we call `foo` in the above is: 1. A new request is created and started. 2. `alert` is called, showing the current value of `data` which is, of course, `undefined` because nothing has ever been assigned to it. 3. `foo` returns. 4. At some point in the future, the request completes and sets the `data` variable. Nothing ever does anything with it, though. Compare with: function foo(url) { var result; new Ajax.Request(url, { onSuccess: function(response) { if (response.responseText.substring(0, 8) === "SUCCESS:") { data = response.responseText.substring(8); } else { data = "(could not get data)"; } alert(data); } }); } Now here's what happens when we call `foo`: 1. A new request is created and started. 2. `foo` returns. 3. At some point in the future, the request completes and sets the `data` variable. 4. `alert` is called, showing the current value of `data` (which is what we just assigned to it). So what do you do about it? Put your processing of the result in the success callback (as above), rather than in the code that's starting the Ajax request. Sometimes this means that you have to provide callbacks to code calling your function. For instance, let's assume that `foo` is supposed to *return* `data` to the caller rather than using `alert`. We now know that `foo` can't do that with a return value -- because `foo` returns before the Ajax call is complete. So how would `foo` pass the information back to the caller? Via a callback: function foo(url, callback) { var data; new Ajax.Request(url, { onSuccess: function(response) { if (response.responseText.substring(0, 8) === "SUCCESS:") { data = response.responseText.substring(8); } else { data = null; } }, onComplete: function() { callback(data); } }); } Here's what happens when we call this version of `foo`: 1. We start a new Ajax request. 2. `foo` returns. 3. At some point in the future, the Ajax call completes. If it's successful at the HTTP level (e.g., the response code is 2xx), Prototype will call the `onSuccess` handler. Our handler checks the response text to see if the call worked at the business logic level (remember our values are "SUCCESS:data" or "ERROR"), and if it was successful we set `data` to the data from the string; if it wasn't, we set `data` to `null`. 4. When the Ajax call completes (regardless of whether it succeeds or fails at the HTTP level), Prototype calls the `onComplete` handler. We call the callback function the caller provided, passing in `data`. If the Ajax request failed at the HTTP level (404, 500), we'll have never set `data` *at all* and so it will be `undefined`. If the Ajax request succeeded at the HTTP level but failed at the business logic level, we set `data` to `null` in the `onSuccess` handler and so it will be `null`. If everything worked, `data` will be the data from the response. So the documentation of our `foo` function would say that the callback will *always* be called back, and will be called back with one of three values: * undefined: The Ajax call failed at the HTTP level * null: The Ajax call succeeded but the server returned an error * a string: The call was successful and this is the data retrieved Now, you probably wouldn't design an API like that (I wouldn't), but I wanted to cover the various ways that `data` is or isn't populated. I'd probably design the API so that the callback received an object with properties saying what happened, something vaguely like this: function foo(url, callback) { var result; result = { success: false, message: "unknown HTTP error", data: undefined }; new Ajax.Request(url, { onSuccess: function(response) { var text = response.responseText || ""; if (text.substring(0, 8) === "SUCCESS:") { result.success = true; result.message = undefined; result.data = text.substring(8); } else { if {text.substring(0, 6) === "ERROR:") { result.message = text.substring(6).strip(); } else { result.message = ""; } if (!result.message) { result.message = "unknown app error"; } } }, onFailure: function(response) { result.message = "HTTP failure code " + response.status; }, onComplete: function() { callback(result); } }); } Now the callback always gets an object, which the caller can easily check for success or failure and (if desired) get more information about the failure if there was one. I will just mention in passing that it's possible to make an Ajax request synchronous instead of asynchronous, but I haven't discussed it above because it's a very, very bad idea. Doing a synchronous Ajax request locks up the browser while the request is in progress. The degree to which it locks up the browser varies depending on which browser you're talking about, but (for instance) on the most common browser in the world (IE) it not only locks up your page, but every page in every tab. (And most of the others aren't much better, partially because they basically *can't* be -- if you have any other JavaScript on the page, they *have* to completely lock it up during a synchronous request.) It's a Bad Thing(tm), hence my not talking about doing it. Embrace the event-driven nature of the environment instead. HTH, -- T.J. Crowder Independent Software Engineer tj / crowder software / com www / crowder software / com On Nov 2, 8:05 pm, laurent barre <houpde...@gmail.com> wrote: > Hi, > > It's the fisrt time that I work with javascript and that I use P.O.O. > javascript. > I saw some lessons on javascript, I start to understand. > > You are right, my problem isn't "this". > > I retried, the problem is in the function "Ajax.Request". > > example code : > > url : function(object) { > new Ajax.Request( > object.php, { > method: object.method, > parameters: {url_analyse : this.value_event}, > onComplete: function (xhr, json){ > if (json) { > var str = ''; > json.each(function (item) { > str += item.reponse; > }); > show_message(str;); > } > }, > } > ); > } > > If the function "show_message" is in " new Ajax.Request()" , the result > corresponds to the Request. > But if the function "show_message" is outside "new Ajax.Request()" then the > result corresponds to the previous Request. > I don't understand why ? > > Thank. > Laurent > > 2010/11/2 T.J. Crowder <t...@crowdersoftware.com> > > > > > > > > > Hi, > > > I'm afraid your question doesn't make a lot of sense, I think a great > > deal has been lost in translation. > > > But `this` is special in JavaScript: It's set entirely by *how a > > function is called*, not *where a function is defined*. This is > > different from other languages. More here: > >http://blog.niftysnippets.org/2008/04/you-must-remember-this.html > >http://api.prototypejs.org/language/function/prototype/bind/ > > > HTH, > > -- > > T.J. Crowder > > Independent Software Engineer > > tj / crowder software / com > > www / crowder software / com > > > On Nov 1, 8:14 pm, laurent barre <houpde...@gmail.com> wrote: > > > Hi, > > > > I have a function Ajax.Responders , but i can't catch the paramater > > "this" > > > and i can't modify the value of the parameter "this". > > > > the result>one : the value is 'url' > > > > >two : equal *"no_good"* > > > > > three : undefined > > > > I try to find a solution, I think that in javascript , the transfert of a > > > global variable(this) is not possible, do you have a solution ? or a > > > explication ? > > > > Code > > ---------------------------------------------------------------------- > > > > *this.element = 'url'; > > > this message = 'no_good'; > > > > trace(this.element); > one > > > > Ajax.Responders.register({ > > > onComplete: function (xhr, json){ > > > if (json) { > > > var str = ''; > > > json.each(function (item) { > > > str += item.reponse; > > > }); > > > this.message = str; > two > > > trace(this.element); > three > > > > } > > > }}); > > > > * > > > Code > > > ------------------------------------------------------------------------ > > > > thanks, > > > > Laurent > > > -- > > You received this message because you are subscribed to the Google Groups > > "Prototype & script.aculo.us" group. > > To post to this group, send email to > > prototype-scriptacul...@googlegroups.com. > > To unsubscribe from this group, send email to > > prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculou > > s%2bunsubscr...@googlegroups.com> > > . > > For more options, visit this group at > >http://groups.google.com/group/prototype-scriptaculous?hl=en. -- You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptacul...@googlegroups.com. To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.