Http call being made twice with parameters reset - angularjs

I'm making a GET request to retrieve posts, but when I load the page, it makes the first request with the correct page query in the request URL but then immediately makes another request with page set to 1. Here's the console output when I make a request for page=3:
"page: 3"
bolt.js:54 Object {method: "GET", url: "http://localhost/api/v1/content/news?order=datepublish%20DESC&limit=10&page=3", headers: Object}
bolt.js:54 Object {method: "GET", url: "http://localhost/api/v1/content/news?order=datepublish%20DESC&limit=10&page=1", headers: Object}
bolt.js:58 "success function called."
posts.controller.js:35 Object {data: Object, status: 200, headers: function, config: Object, statusText: "OK"}
bolt.js:58 "success function called."
So you can see it's clearly making two GET requests, but only returning one set of data (the latter, with page=1.
In my posts.controller.js, I have:
activate();
function activate() {
$scope.isLoading = 1;
$scope.previousLink = 0;
return getPosts($stateParams.page).then(function(data) {
$scope.isLoading = 0;
$rootScope.pageLoading = 0;
});
}
function getPosts(page) {
console.log("page: " + page);
var contenttype = 'news';
var order = 'datepublish%20DESC';
var limit = 10;
return Bolt.getRecords(contenttype, order, limit, page)
.then(function(data){
// Below is line 35
console.log(data);
$scope.posts = data.data.data;
});
}
And the Bolt service (bolt.js):
function getRecords(contenttype, order, limit, page) {
var request = {
method: 'GET',
url: API_BASE_URL + 'content/' + contenttype +
'?order=' + order +
'&limit=' + limit +
'&page=' + page,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
};
// Below is line 54
console.log(request);
return $http(request)
.success(function(data){
// Below is line 58
console.log("success function called.");
return data;
})
.error(function(error){
return error;
});
}
What am I doing wrong here?

Sometimes there are asynchronous function calls made within a watch that are executed via the digest cycle.
Check if you have used your getRecords or getPosts function anywhere else in your code. Perhaps is related to watching some variable related to your pages parameter.
Good luck.

Related

how to receive array data in ajax request page wordpress

I am sending array to PHP through angularJs $http, but when I receiving data it was showing null, I don't know is that my procedure is correct or not,
js file is
var newdisable_comments_on_post_types = JSON.stringify(allTabData.disable_comments_on_post_types);
$http({
method:'post',
url:url,
params:{
'disable_comments_on_post_types': newdisable_comments_on_post_types
}
});
while sending in the header it sending like this
disable_comments_on_post_types:{"post":false,"page":false,"attachment":false}
in the PHP file, i did some of the procedure to receive it
$a = $_POST['disable_comments_on_post_types']['post'];// method 1
$a = $_POST['disable_comments_on_post_types'] // method 2
$x=1
foreach($a as $val){
$b[$x]=$val;
$x++;
}
$a = $_POST['disable_comments_on_post_types']->post;// method 3
I am getting null in response every method while I returning data to check
echo json_encode($a);
am I doing any wrong or in WordPress we cant send an array to PHP?
Change Your $http service to this:
By default, the $http service will transform the outgoing request by
serializing the data as JSON and then posting it with the content-
type, "application/json"
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: allTabData.disable_comments_on_post_types
}).success(function () {});

AngularJS - POST request does not send data after first request was successfully made

This is really weird. I am using AngularJS in my app. During login, I make an HTTP POST request ; data is sent properly and I receive the right response. Then I logout - which returns me back to the login page - and I do the same http req but the data is not sent by the post request. Upon console.log I see that the $scope data is correct - just the POST data is not being sent.
If I do a hard refresh of the login page it works again. So my problem is that consecutive requests are not being made without refreshes. Here is my login function -
$scope.login = function() {
var request = $http({
method: "POST",
url: URL + "login",
crossDomain: true,
data: this.loginData
});
request.success(function(data) {
var response = angular.fromJson(data);
if(!response["error"]) {
sessionStorage.email = response["email"];
sessionStorage.password = response["password"];
sessionStorage.userId = response["id"];
$location.path('/dashboard');
} else {
$scope.responseMessage = response["message"][0];
}
});
request.error(function(data) {
console.log(data);
});
}
And this is my logout function -
$scope.logout = function() {
sessionStorage.clear();
$location.path("/login");
}
Found the answer and posting it here in case anyone runs into a similar problem.
Setting a header for content type works:
var request = $http({
method: "POST",
url: URL + "login",
crossDomain: true,
headers: {
"content-type": "application/json"
},
data: this.loginData
});

AngularJS Trigger callback after ForEach

I'm currently developing an AngularJS form which on submit pushes single or multiple participant data to an SQL database.
I'm able to push data to the SQL database, but I'm wanting to trigger a callback that redirects the user once all participant data has been successfully submitted.
At the moment on success it redirects the user but, misses the next foreach submit for the next participant.
Any and all advice would be appreciated.
AngularJS
/* Submit */
$scope.submit = function() {
var array = $scope.form.participants;
//console.log(array);
angular.forEach(array, function(value, key){
var request = $http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
contactArea: $scope.form.program.contractArea,
postcode: $scope.form.program.postcode,
programmeStart: $scope.form.program.programmeDate,
sessionDate: $scope.form.program.sessionDate,
sessionNumber: $scope.form.program.sessionNumber,
weekNumber: $scope.form.program.weekNumber,
id: value.participant.id,
attendance: value.participant.attendance,
weight: value.participant.weight,
goldBehaviours: value.participant.goldBehaviours,
stepCount: value.participant.stepCount,
creditData: value.participant.creditData,
weekOne: value.participant.weekOne,
stepOne: value.participant.stepOne,
weekTwo: value.participant.weekTwo,
stepTwo: value.participant.stepTwo,
weekThree: value.participant.weekThree,
stepThree: value.participant.stepThree,
weekFour: value.participant.weekFour,
stepFour: value.participant.stepFour,
weekFive: value.participant.weekFive,
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
//console.log(data);
$location.path("/thankyou");
});
});
};
Data
{
"program":{
"coachName":"AD",
"contractArea":"Berkshire",
"postcode":"NN1",
"programmeDate":"2016-08-15T23:00:00.000Z",
"sessionDate":"2016-08-16T23:00:00.000Z",
"sessionNumber":"1",
"weekNumber":"2"
},"participants":[
{"participant":{"id":"AW01","attendance":"Did Not Attend","weight":"1","goldBehaviours":"2","stepCount":"3","creditData":"","weekOne":"4","stepOne":"4","weekTwo":"5","stepTwo":"5","weekThree":"6","stepThree":"6","weekFour":"7","stepFour":"7","weekFive":"8","stepFive":"8"}},
{"participant":{"id":"AW02","attendance":"Attended","weight":"2","goldBehaviours":"3","stepCount":"4","creditData":"","weekOne":"5","stepOne":"5","weekTwo":"6","stepTwo":"6","weekThree":"7","stepThree":"7","weekFour":"8","stepFour":"8","weekFive":"9","stepFive":"9"}}
]
}
You can inject $q to your controller/service and use $q.all method (you can also use native Javascript Promise if you're not worried about old browsers support).
The all method takes an array of promises and resolve when all promises in the array resolve (it will reject if any of the promises reject).
$scope.submit = function() {
var array = $scope.form.participants;
var promises = [];
//console.log(array);
angular.forEach(array, function(value, key){
promises.push($http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
...
...
...
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}));
});
$q.all(promises).then(function() {
$location.path("/thankyou");
});
};
You are telling it to redirect with each iteration, not after all iterations have been completed. Try moving your redirect like so:
angular.forEach(array, function(value, key){
var request = $http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
contactArea: $scope.form.program.contractArea,
postcode: $scope.form.program.postcode,
programmeStart: $scope.form.program.programmeDate,
sessionDate: $scope.form.program.sessionDate,
sessionNumber: $scope.form.program.sessionNumber,
weekNumber: $scope.form.program.weekNumber,
id: value.participant.id,
attendance: value.participant.attendance,
weight: value.participant.weight,
goldBehaviours: value.participant.goldBehaviours,
stepCount: value.participant.stepCount,
creditData: value.participant.creditData,
weekOne: value.participant.weekOne,
stepOne: value.participant.stepOne,
weekTwo: value.participant.weekTwo,
stepTwo: value.participant.stepTwo,
weekThree: value.participant.weekThree,
stepThree: value.participant.stepThree,
weekFour: value.participant.weekFour,
stepFour: value.participant.stepFour,
weekFive: value.participant.weekFive,
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
//console.log(data);
});
$location.path("/thankyou");
});
Your redirect needs to be outside of your forEach.

AngularJS HTTP GET request returning cached data

In my AngularJS app I am sending HTTP GET request as below.
MyService.HttpReq("testUrl", "GET", null);
HttpReq Method is defined in a service and implemented as below:
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: postData,
headers: {
'Content-Type': 'application/json',
}
}).success(function(response)
{
console.log("Success: "+JSON.stringify(response));
}).error(function(data, status)
{
console.error("Error");
});
}
First of all is this the right way of sending HTTP request in AngularJS?
The problem that I am facing is, some times I get cached data as response and HTTP request is not hitting the server. what can be the issue?
UPDATE
As per the comment and answer I have updated my HTTP request code as below, but still getting same issue.
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: payload,
headers: {
'Content-Type': 'application/json',
'Cache-Control' : 'no-cache'
}
}).
then(
function(response)
{
var data = response.data;
console.log("Success: "+JSON.stringify(data));
},
function(response)
{
var data = response.data || "Request failed";
var status = response.status;
console.error("Error: "+JSON.stringify(data));
}
);
}
IE Browsers will catch ajax get requests even if we add cache control headers to the response. Only way i found to solve the issue is to add some random parameter to the request. Please make sure the api have no problem even if you send extra parameters
MyService.HttpReq("testUrl?ts=" + Date.now(), "GET", null);
Just add cache: false attribute to config object.
https://docs.angularjs.org/api/ng/service/$http#caching
Also you can add header: 'Cache-Control' : 'no-cache'

How to reset global Basic Authentication header in AngularJS?

In my angular app the global $http headers are defined for every request, like this:
function useBasicAuth(username, hash) {
var encoded = btoa(username + ':' + hash);
$http.defaults.headers.common.Authorization = 'Basic ' + encoded;
}
How to disable sending this information, when for example the user logs out, and the authentication is no longer required?
What I found as a working solution was to redeclare the $http.defaults.headers.common Object so it won't contain the headers.
Example:
function useBasicAuth(username, hash) {
var encoded = btoa(username + ':' + hash);
$http.defaults.headers.common.Authorization = 'Basic ' + encoded;
}
This, however won't delete the cached credentials from the browser. To overcome this, I've made a simple - and not asynch call to generate a bad request on purpose.
This is the function for this in my accountServices factory:
function checkAuth(username, hash) {
var encoded = btoa(username + ':' + hash);
var result = false;
$.ajax({
type: "POST",
beforeSend: function (request) {
request.setRequestHeader("Authorization", 'Basic ' + encoded);
},
url: "user/current",
statusCode: {
401: function () {
result = false;
},
200: function (response) {
result = response;
}
},
async: false
});
return result;
}
To log the user out, I call this function:
function useBasicWithoutAuth() {
accountServices.checkAuth('logout','logout');
$http.defaults.headers.common = {Accept: "application/json, text/plain, */*"};
}
So what this does, is it first sends a request to a protected URL, with a fake and non-existant user, so it's basically the same, as if the prompt would appear to you, and you'd click cancel.
After this has been done, there's no cached data in the browser, we can simply remove the headers from Angular, so it won't send any Authorization information, where it's not needed.

Resources