Hi,

Thank,

Laurent

2010/11/3 T.J. Crowder <t...@crowdersoftware.com>

> 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-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
> s%2bunsubscr...@googlegroups.com <s%252bunsubscr...@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<prototype-scriptaculous%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.

Reply via email to