Search code examples
androidcordovaphonegap-buildhybrid-mobile-app

Cordova Android emulator app not invoking http POST method to the RESTful php server?


I am developing android app using cordova on Ubuntu 14. Its a hybrid app that consists of:- Server- RESTful api using Php with slim framework &
Client - Backbone with requirejs,jquery,bootstrap etc.., HTML,CSS.

I have created the app as per the steps given in Apache Cordova Documentation guide (http://cordova.apache.org/docs/en/5.0.0/guide_platforms_android_index.md.html#Android%20Platform%20Guide) and imported the app in android studio. I am using android studio 1.3.

I have connected the app to my localhost using(10.0.2.2), the app runs on the emulator and shows the 'login' screen.

The challange is, after filling user name and password, when I click 'Sign In' it should trigger http 'POST' as in Browser app. But it does not triggers POST and in return I get 404 error in Backbone.sync-error, and when I saw the server HTTP_METHOD it shows 'GET' !!

I have overriden Backbone.sync method.

This is my 'login.js' file triggering the event

//sigin button click code ...
// ...
signinInfo.set({
email: email,
password: password     
});
signinInfo.save(null,{
success: function (data) {    
    window.localStorage.setItem('uid',signinInfo.attributes.uid);             
window.localStorage.setItem('email_id',signinInfo.attributes.email_id);
// redirect the user to the given route                    
if (data.attributes.status == "1") {                         
    window.location.href = "";                         
} else {
    alert("Incorrect password!");                       
}
}   // success
});

The above 'save' on 'signinInfo' model triggers the Backbone.sync method. Here's the code snippet from models.js that overrides 'Backbone.sync' method:

originalSync = Backbone.sync;
Backbone.sync = function (method, model, options) {
    var success = options.success;
    var error = options.error;        
    console.log("Models.js- method: " + method + ", model: " + JSON.stringify(model) + ", options: " + JSON.stringify(options));

    options.success = function (model, response, options) {
        console.log("Models.js- success, response: " +response );
        $('.srLoading').hide();
        if (typeof model.redirect == 'undefined') {
            success(model, response, options);
        } else {
            window.location.replace("/");
        }
    };
    options.error = function (model, response, options) {
        console.log("Models.js- error:" +JSON.stringify(model) + " response: " + response + "; options: " + JSON.stringify(options));
        $('.srLoading').hide();
        error(model, response, options);
    };
  // I have tried to put options for crossDomain here, but its not working
    options = options || (options = {});

    if (!options.crossDomain) {
        options.crossDomain = true;
    }

    if (!options.xhrFields) {
        options.xhrFields = {withCredentials:true};
    }
    if (method === "read") {
        console.log("Models.js- read method!" );
        $('.srLoading').show();
        options.dataType = "jsonp";
        return originalSync.apply(Backbone, arguments);
    }

    if (method === "create") {
        console.log("Models.js- create method!" );
        $('.srLoading').show();
        options.dataType = "jsonp";

        options.contentType = 'application/json';
        options.type = 'POST';
        //options.data = JSON.stringify(options.data);

        return originalSync.apply(Backbone, arguments);
    }

    if (method === "update") {
        $('.srLoading').show();
        options.dataType = "jsonp";
        return originalSync.apply(Backbone, arguments);
    }
    if (method === "delete") {
        $('.srLoading').show();
        options.dataType = "jsonp";
        return originalSync.apply(Backbone, arguments);
    }
}; //Backbone.sync

Above, method 'create' is called but at server it does not converts to 'POST' request. Instead $_SERVER['REQUEST_METHOD'] shows 'GET'! :(


Solution

  • In my Backbone.sync method I commented [options.dataType = "jsonp";] so that the code looks as follows:

    ...
    if (method === "create") {
        console.log("Models.js- create method!" );
        $('.srLoading').show();
        //options.dataType = "jsonp";
        options.contentType = 'application/json';
        return originalSync.apply(Backbone, arguments);
    }
    

    Now my login sends HTTP POST request to the server!

    On cross domain (CORS), backbone with dataType 'jsonp' can only make 'GET' request. So to make other actions we need to send 'json' data.