1. #1
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default Synchronous Ajax Call

    Synchronous Ajax Call


    This is in response to this thread.

    I agree that it is ideal to use async requests as much as possible, even if it requires refactoring much of your other code to make it work that way. However, there is value in having the option to make a synchronous call if one should wish, and there are situations where it may be desired. Not to mention that many people have requested this functionality.

    Anyway, here it is:
    Code:
    Ext.lib.Ajax.request = function(method, uri, cb, data, options) {
    	if (options) {
    		var hs = options.headers;
    		if (hs) {
    			for (var h in hs) {
    				if (hs.hasOwnProperty(h)) {
    					this.initHeader(h, hs[h], false);
    				}
    			}
    		}
    		if (options.xmlData) {
    			this.initHeader('Content-Type', 'text/xml', false);
    			method = 'POST';
    			data = options.xmlData;
    		}
    		var async = (options.async === false) ? false : true;
    	}
    
    	return this.asyncRequest(method, uri, cb, data, async);
    };
    
    Ext.lib.Ajax.asyncRequest = function(method, uri, callback, postData, async) {
    	var o = this.getConnectionObject();
    
    	if (!o) {
    		return null;
    	}
    	else {
    		o.conn.open(method, uri, async);
    	
    		if (this.useDefaultXhrHeader) {
    			if (!this.defaultHeaders['X-Requested-With']) {
    				this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
    			}
    		}
    	
    		if (postData && this.useDefaultHeader) {
    			this.initHeader('Content-Type', this.defaultPostHeader);
    		}
    	
    		if (this.hasDefaultHeaders || this.hasHeaders) {
    			this.setHeader(o);
    		}
    	
    		this.handleReadyState(o, callback);
    		o.conn.send(postData || null);
    	
    		return o;
    	}
    };
    Example:
    Code:
    Ext.Ajax.request({
    	url: 'some_page.php',
    	method: 'POST',
    	success: success,
    	failure: failure,
    	scope: this,
    	params: {foo: 'bar'},
    	async: false
    });
    
    
    // or directly ...
    Ext.lib.Ajax.request('POST', url, callback, params, {async: false});

    DISCLAIMER: This is ONLY for use with ext-base.js.

  2. #2
    Ext User
    Join Date
    Apr 2008
    Posts
    2
    Vote Rating
    0
    Victor Hugo Borja is on a distinguished road

      0  

    Default Update

    Update


    Hi, I needed to make some synchronous requests using ExtJS and tried the solution posted in the previous post, however it didn't work for me, even thought the XMLHttpRequest was synchronous, Ext.lib.Ajax was handling the response as if it were async (using setInterval), that caused the Ext.lib.Ajax.request function to return just before the XMLHttpRequest was performed, giving an async feeling. So I just updated the code previously posted here that creates a syncRequest function on Ext.lib.Ajax to handle synchronous requests.

    Usage is the same as described on previous post.

    Code:
    /* -*-js2-*- */
    Ext.lib.Ajax.request = function(method, uri, cb, data, options) {
        if(options){
            var hs = options.headers;
            if(hs){
                for(var h in hs){
                    if(hs.hasOwnProperty(h)){
                        this.initHeader(h, hs[h], false);
                    }
                }
            }
            if(options.xmlData){
                this.initHeader('Content-Type', 'text/xml', false);
                method = 'POST';
                data = options.xmlData;
            }else if(options.jsonData){
                this.initHeader('Content-Type', 'text/javascript', false);
                method = 'POST';
                data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
            }
            if (options.async == false) {
                return this.syncRequest(method, uri, cb, data);
            }
        }
        return this.asyncRequest(method, uri, cb, data);
    };
    
    
    Ext.lib.Ajax.syncRequest = function(method, uri, callback, postData)
    {
        var o = this.getConnectionObject();
    
        if (!o) {
            return null;
        }
        else {
            o.conn.open(method, uri, false);
    
            if (this.useDefaultXhrHeader) {
                if (!this.defaultHeaders['X-Requested-With']) {
                    this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
                }
            }
    
            if(postData && this.useDefaultHeader){
                this.initHeader('Content-Type', this.defaultPostHeader);
            }
    
            if (this.hasDefaultHeaders || this.hasHeaders) {
                this.setHeader(o);
            }
    
            o.conn.send(postData || null);
            this.handleTransactionResponse(o, callback);
            return o;
        }
    };

  3. #3
    Ext User
    Join Date
    Nov 2007
    Posts
    23
    Vote Rating
    0
    DomZ is on a distinguished road

      0  

    Default


    Hi,

    I a mvery interested by this code, but i would like to know where i have to paste these methods in the extjs code ?

    Thanks

  4. #4
    Ext User
    Join Date
    Apr 2008
    Posts
    2
    Vote Rating
    0
    Victor Hugo Borja is on a distinguished road

      0  

    Default


    You don't have to patch the source to use it, just place the code on a sync.js file, and load it in your page just after loading ext.

  5. #5
    Sencha User
    Join Date
    May 2007
    Posts
    6
    Vote Rating
    0
    faisalv is on a distinguished road

      0  

    Default


    There is a less-intrusive way to do this too:

    Code:
    Ext.lib.Ajax.originalRequest = Ext.lib.Ajax.request;
    Ext.lib.Ajax.originalAsyncRequest = Ext.lib.Ajax.asyncRequest;
    Ext.lib.Ajax.request = function(method, uri, cb, data, options) {
        if ( options.sync === true )
        {
          this.asyncRequest = function() {
            this.asyncRequest = Ext.lib.Ajax.originalAsyncRequest; // we don't really need this ...
            this.syncRequest.apply(this,arguments); // refer to previous posts for code to this
          }
        }
        else
        {
          this.asyncRequest = Ext.lib.Ajax.originalAsyncRequest; // reset this - just in case we had some errors executing the body of request()
        }
        this.originalRequest.apply(this, arguments);
    };

  6. #6
    Sencha User
    Join Date
    Mar 2008
    Posts
    27
    Vote Rating
    0
    neoart is on a distinguished road

      0  

    Default


    Dear All:
    Thanks for all of your contribution,it matches my requirement
    But I don't know if you found another problem caused by this "patch" that:
    in IE,the "Ext.MessageBox.show" no longer showen when I add faisalv's & Victor Hugo Borja 's js code ,but "Ext.MessageBox.show" shows in firefox.
    Did anyone also had such problem? and how to solve it?
    Thanks for any reply

    Regards
    john

  7. #7
    Ext JS Premium Member
    Join Date
    Mar 2007
    Posts
    173
    Vote Rating
    0
    MaxT is on a distinguished road

      0  

    Default Update for Ext 2.2

    Update for Ext 2.2


    I've had a go at updating this to match the Ext2.2 code.

    The only bit I wasn't too sure about was the setting of headers.
    E.g. the code...

    Code:
    hs['Content-Type']
    This doesn't look right to me. I always thought that a hyphen was an invalid character for property names because it gets interpreted as a subtraction sign.
    i.e.
    Code:
    hs.Content-Type
    is the same as
    Code:
    (hs.Content)-Type
    which is obvioulsy wrong. Maybe you can always get away with it if you only access the property via the square bracket notation?

    Anyway, here is the code.

    Max

    HTML Code:
    /**
    Adding a synchronous request to the Ext asynchronous only mode of operation.
    
    History: coded from Ext 2.2.
    
    Additional configs.
    
    @param {Object} options
    @config {Mixed} [sync] include this for a synchronous request
    */
    Ext.lib.Ajax.request = function(method, uri, cb, data, options) {
        if(options){
            var hs = options.headers;
            if(hs){
                for(var h in hs){
                    if(hs.hasOwnProperty(h)){
                        this.initHeader(h, hs[h], false);
                    }
                }
            }
            if(options.xmlData){
                if (!hs || !hs['Content-Type']){
                    this.initHeader('Content-Type', 'text/xml', false);
                }
                method = (method ? method : (options.method ? options.method : 'POST'));
                data = options.xmlData;
            }else if(options.jsonData){
                if (!hs || !hs['Content-Type']){
                    this.initHeader('Content-Type', 'application/json', false);
                }
                method = (method ? method : (options.method ? options.method : 'POST'));
                data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
            }
        }
    
        return this["sync" in options ? "syncRequest" : "asyncRequest"](method, uri, cb, data);
    
    };
    
    
    /**
    Synchronous request.  
      
    @param {Object} method
    @param {Object} uri
    @param {Object} callback
    @param {Object} postData
    */
    Ext.lib.Ajax.syncRequest = function(method, uri, callback, postData)
    {
        var o = this.getConnectionObject();
    
        if (!o) {
            return null;
        }
        else {
            o.conn.open(method, uri, false);
    
            if (this.useDefaultXhrHeader) {
                if (!this.defaultHeaders['X-Requested-With']) {
                    this.initHeader('X-Requested-With', this.defaultXhrHeader, true);
                }
            }
    
            if(postData && this.useDefaultHeader && (!this.hasHeaders || !this.headers['Content-Type'])){
                this.initHeader('Content-Type', this.defaultPostHeader);
            }
    
            if (this.hasDefaultHeaders || this.hasHeaders) {
                this.setHeader(o);
            }
    
            o.conn.send(postData || null);
            this.handleTransactionResponse(o, callback);
            return o;
        }
    };
    

  8. #8
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    91
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    I thought everybody used the ext-basex user extension for synchronous AJAX requests.

  9. #9
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,503
    Vote Rating
    47
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Can anyone provide a use case for synchronous requests?

  10. #10
    Ext JS Premium Member
    Join Date
    Mar 2007
    Posts
    173
    Vote Rating
    0
    MaxT is on a distinguished road

      0  

    Default Ext-basex

    Ext-basex


    Ext-basex requires a Commercial licence. I don't see the point in buying one just to be able to do a synchronous request which can be coded in a few lines.

    Max