3

Whenever I launch my app, and click on login on the first few tries, the login will attempt a POST http to the server. However $http always (everytime) returns NULL on first try. sometimes after several few tries still NULL if done fast. But subsequently, its all ok.

I dont get it, why is $http returning error response NULL initially ??

Here is my login controller doing the http post

Login Controller (LoginCtrl) https://gist.github.com/anonymous/771194bc5815e4ccdf38b57d6158853f

var req = {
  method: 'POST',
  url: baseURL,
  data: postObject,
  //timeout: 5000
};

err is NULL here:

}).error(function(err) {

I dont know if it is CORS but I'ved got this set in config.xml

 <access origin="*" />

my config.xml https://gist.github.com/anonymous/b2df3a857338d14ec3fcd6dda776e212

Any ideas ? Im using ionic 1.7.14 on device iOS 9.3.1

UPDATE

I'ved put the problem code here. can logout first to goto login screen. enter in anything in username/password field, click login once failed, second or third try will be success.

https://github.com/axilaris/ionic_null_http_problem

some troubleshooting so far: i noticed the http post request is called twice. not sure why.

UPDATED the code using $http.post.then but still has the same effect

 $http.post(baseURL, postObject).then(function successCallback(response)

 response has NULL data --> Object {data: null, status: 0, config: Object, statusText: ""}
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Axil
  • 3,606
  • 10
  • 62
  • 136

3 Answers3

0

It is hard to diagnose having the above details only. However the problem could be that your handler (login function) is triggered before digest cycle finished updating $scope.data.username and $scope.data.password and for the first tries it sends empty values for those to the server and works fine later. You can run Safari web inspector to see what is sent to the server to prove this. The fix may depend on how your view/template is coded. Can you please share it? Or, ideally, create a working sample at http://play.ionic.io/

Another option to fix could be to try to wrap your code related to http request into

$timeout(function() { 
    // your code goes here
});

or, consider using .$applyAsync() (see the docs for details) This might help to fix the problem

Alex Ryltsov
  • 2,385
  • 17
  • 25
  • I'ved put the problem source here: https://github.com/axilaris/ionic_null_http_problem. it happens on web with "ionic serve" as well. one thing i noticed, the http post gets called twice. not sure why. – Axil Apr 20 '16 at 02:50
  • In the code you posted username and password are not passed to the server. See https://github.com/axilaris/ionic_null_http_problem/blob/master/www/js/controllers.js#L114. Besides this there is a problem with cross domain call. I got XMLHttpRequest cannot load https://www.veejansh.com/vurja/mobile.php. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8099' is therefore not allowed access. – Alex Ryltsov Apr 26 '16 at 13:33
  • U would need cors chrome extension to get it working, username&password not required. Its a timeout issue – Axil Apr 27 '16 at 07:50
0

You are probably getting this inconsistent behavior as you are using the 'success' promise method instead of 'then' (note that use of the success method has now been deprecated).

The key differences between these two methods are:

  • then() - full power of the promise API but slightly more verbose
  • success() - doesn't return a promise but offeres slightly more convienient syntax

as highlighted in this answer.

Hence in your scenario, instead of using 'success':

var req = {
  method: 'POST',
  url: baseURL + 'session/login',
  data: postObject,
  //timeout: 5000
};

$http(req).success(function(resp) {...

use 'then' along with angular's post shortcut method (you don't have to use this shortcut method, but I think it makes the code more succinct) e.g.:

$http.post(baseURL + 'session/login', postObject).then(function successCallback(response) {
  // this callback will be called asynchronously
  // when the response is available
}, function errorCallback(response) {
  // called asynchronously if an error occurs
  // or server returns response with an error status.
});

Using 'then' returns a promise resolved with a value returned from a callback, so it should give you a consistently valid result.

Community
  • 1
  • 1
Ben Smith
  • 19,589
  • 6
  • 65
  • 93
  • Thanks for your tip. I updated the code using $http.post.then, its still the same behaviour. first few tries failed then successCallback. I'ved updated the code in github with your advise if you are keen to try it. Thanks. – Axil Apr 21 '16 at 23:25
  • I really did think it was due to the success method. When you say $http returns null what exactly do you mean? Do you mean that http returns a null promise? Is any of your console.log statements being output when you get your null result? – Ben Smith Apr 21 '16 at 23:37
  • currently errorCallback(response). console.error('ERROR', response); retuns this -----> ERROR, Object {data: null, status: 0, config: Object, statusText: ""} – Axil Apr 21 '16 at 23:47
  • 1
    previous code, }).error(function(err) { the err variable returns null. ok i should change the title. my bad. – Axil Apr 21 '16 at 23:48
  • It could also be that your connection is not initialised when you start the app. Perhaps there is an issue with how your checking the connection (though it does look ok). Instead of using "if (window.cordova){..." you could try "if(window.Connection) {..." see [this](http://codepen.io/tahababa/pen/ZYYwEX) example. – Ben Smith Apr 21 '16 at 23:58
  • Connection is OK. i tried with if(window.Connection), put it in separate branch testconnection_branch – Axil Apr 22 '16 at 00:06
  • Do you get different behaviour when you debug compared to when you just run the app? – Ben Smith Apr 22 '16 at 00:12
  • same on ionic serve and on ios device. so its able to reproduce the same behaviour on web debugging. – Axil Apr 22 '16 at 00:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109857/discussion-between-bensmith-and-axil). – Ben Smith Apr 22 '16 at 00:15
0

it was a timeout in app.js that caused it. was set to 1 second which gives it it arbitrary success rate.

config.timeout = 1000;
Axil
  • 3,606
  • 10
  • 62
  • 136