I am really new to Angular. I am trying to pass a variable to php but the response is " Notice: Trying to get property of non-object" and null for the array.
js file:
var myData = {
fruit1: 'apple',
fruit2: 'banana'
};
$http({
url: "test.php",
method: "POST",
headers : { 'Content-Type': 'application/json' },
data: myData
}).success(function(data, status, headers, config) {
$scope.data = data;
}).error(function(data, status, headers, config) {
$scope.status = status;
});
php file:
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$data = $request->myData;
var_dump($data);
The .success and .error methods have been removed from the AngularJS framework. Instead, use the .then and .catch methods:
var myData = {
fruit1: 'apple',
fruit2: 'banana'
};
$http({
url: "test.php",
method: "POST",
̶h̶e̶a̶d̶e̶r̶s̶ ̶:̶ ̶{̶ ̶'̶C̶o̶n̶t̶e̶n̶t̶-̶T̶y̶p̶e̶'̶:̶ ̶'̶a̶p̶p̶l̶i̶c̶a̶t̶i̶o̶n̶/̶j̶s̶o̶n̶'̶ ̶}̶,̶
data: myData
}).then(function(response) {
$scope.data = response.data;
return response.data;
}).catch(function(err) {
$scope.status = err.status;
throw err;
});
The $http service automatically JSON encodes data and automatically sets the content type to application/json.
In this case, the code does not use the promise returned by the .then and .catch methods. If the promise is used, it is important to have return and throw statements in the success and rejection handlers.
php file:
$postJSON = file_get_contents("php://input");
$dataArr = json_decode($postJSON, TRUE);
var_dump($dataArr);
The JSON encoded data is found in the body of the POST request. The name of the variable is not sent, only the contents.
The second argument of the json_decode function, specifies that objects be converted to associative arrays.
Keep in mind that these POST requests are subject to same-origin policy. The XHR request must be made from a website page that has the same origin as the page receiving the POST request.
so I am creating Google Chrome Extension and at first I was injecting my html, angular and javascripts via content script. No I need to inject it by my own. I made that! But the problem is that when it was injected via content script my login method worked just fine in return I got token (that's what I needed), but when injected by myself my login function does not work anymore and it throws this error:
XMLHttpRequest cannot load http://www.cheapwatcher.com/api/Authenticate. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://anywebsitename.com' is therefore not allowed access. The response had HTTP status code 400.
This is my login method (I haven't changed anything since changed the injection type):
angular.module('app').controller('LoginController', LoginController);
LoginController.$inject = ['$scope', '$http', '$location', '$state'];
function LoginController($scope, $http, $location, $state) {
$scope.login = function (user) {
user.grant_type = 'password';
return $http({
method: 'POST',
url: 'http://www.cheapwatcher.com/api/Authenticate',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Access-Control-Allow-Origin': '*'
},
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: user
}).success(function (result) {
console.log(result);
$(".cheap-watcher").fadeOut(1500, function () {
$(".cheap-watcher").fadeIn($state.go("logout"), {}, { location: false }).delay(2000);
})
}).error(function (result) {
console.log(result);
});
};
};
Can I do something without making CORS on server side? Because as I said injecting via content script works just fine
UPDATE!
So I changed my login method from $http to $.ajax. Everything is the same just instead of $http I wrote $.ajax and removed headers section. In chrome source control the error is the same, but now in fiddler I can see that my request was successful. How is that possible?
now login method looks like this:
angular.module('app').controller('LoginController', LoginController);
LoginController.$inject = ['$scope', '$http', '$location', '$state'];
function LoginController($scope, $http, $location, $state) {
$scope.login = function (user) {
user.grant_type = 'password';
return $.ajax({
url: "http://www.cheapwatcher.com/api/Authenticate",
crossDomain: true,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
method: 'POST',
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: user
}).success(function (result) {
console.log(result);
$(".cheap-watcher").fadeOut(1500, function () {
$(".cheap-watcher").fadeIn($state.go("logout"), {}, { location: false }).delay(2000);
})
}).error(function (result) {
console.log(result);
});
};
};
UPDATE NR. 2!
I saw that error is coming from http://anywebsitename.com 's index page. So I assume that my login request is running not from my extension but from website content. Are there any communication possible from injected script to background script?
Take a look at Requesting cross-origin permissions, you can add http://www.cheapwatcher.com/api/Authenticate to permissions sections.
By adding hosts or host match patterns (or both) to the permissions section of the manifest file, the extension can request access to remote servers outside of its origin.
To use CORS within Angular, we need to tell Angular that we’re using CORS. We use the
.config() method on our Angular app module to set two options.
We need to tell Angular to use the XDomain and
We must remove the X-Requested-With header from all of our requests
angular.module('myApp')
.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers
.common['X-Requested-With'];
});
(function(){
app = angular.module('mySupport',['ngRoute']).controller('knwCenterCtrl');
var config = {
headers : {
'Accept': 'application/vnd.*********+json',
'Accept-Encoding': 'gzip,deflate',
'custom-header': '12345',
'Access-Control-Request-Headers': 'Accept, custom-header'
},
responseType: 'json'
};
app.controller('knwCenterCtrl', function($scope, $http) {
$http.get("https://abcdefg.com/support/pub/navigation/products", config)
.success(function(response)
{
$scope.prodFam = response.productFamily;
// console.log($scope.mycases);
});
});
})();
What am I missing in this get request? I was able to successfully invoke another APi from the same server using the same code. But for some reason, the code is not making any call to the server. Why is that? Please help.
Thanks,
as i am working on angular js for using the rest-full web services in my website,
but my problem is i am getting controll into error field instead of success and i stucked into it since past three days any help will be appreciated more, and this is my anguls js code.
`
function customersController1($scope, $http) {
$http({
url: 'http://localhost:9090/quote',
dataType: 'text/json',
method: 'GET',
headers: {
"Content-Type": "application/json"
}
}).success(function(data){
$scope.data = data;
alert(data);
}).error(function(error){
$scope.error = error;
alert('error');
});
}
</script>
`enter code here`<div ng-controller="customersController1">
<!-- div>{{ quotes }}</div-->
<ul>
cc <li ng-repeat="quotes"> cc{{ quotes }}</li>
</ul>
</div>`
thanks in advance friends.
First make sure the url is working by accessing it in browser and then ensure sure you are using ng-app in your html .
Next -
$http's config object doesn't have ant property 'dataType'. you can remove and try your example.
$http(
{
method : 'GET',
url : 'http://localhost:9090/quote',
}
).success( function(data, status, headers, config)
{
})
.error(function(data, status, headers, config)
{
});
or else you can even use $http's get method to for http get calls.
var config = {};
$http.get('http://localhost:9090/quote', config)
.success(function(data, status, headers, config) {})
.error(function(data, status, headers, config) {});
To know more, read - https://docs.angularjs.org/api/ng/service/$http#get
A note - content-type header is usually sent in http request header while making an POST/PUT call to specify the content type sent from client to server. In your case, you may not need the header.
To know more read - http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
I have some old code that is making an AJAX POST request through jQuery's post method and looks something like this:
$.post("/foo/bar", requestData,
function(responseData)
{
//do stuff with response
}
requestData is just a javascript object with some basic string properties.
I'm in the process of moving our stuff over to use Angular, and I want to replace this call with $http.post. I came up with the following:
$http.post("/foo/bar", requestData).success(
function(responseData) {
//do stuff with response
}
});
When I did this, I got a 500 error response from the server. Using Firebug, I found that this sent the request body like this:
{"param1":"value1","param2":"value2","param3":"value3"}
The successful jQuery $.post sends the body like this:
param1=value1¶m2=value2¶m3=value3
The endpoint I am hitting is expecting request parameters and not JSON. So, my question is is there anyway to tell $http.post to send up the javascript object as request parameters instead of JSON? Yes, I know I could construct the string myself from the object, but I want to know if Angular provides anything for this out of the box.
I think the params config parameter won't work here since it adds the string to the url instead of the body but to add to what Infeligo suggested here is an example of the global override of a default transform (using jQuery param as an example to convert the data to param string).
Set up global transformRequest function:
var app = angular.module('myApp');
app.config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
}
});
That way all calls to $http.post will automatically transform the body to the same param format used by the jQuery $.post call.
Note you may also want to set the Content-Type header per call or globally like this:
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
Sample non-global transformRequest per call:
var transform = function(data){
return $.param(data);
}
$http.post("/foo/bar", requestData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: transform
}).success(function(responseData) {
//do stuff with response
});
If using Angular >= 1.4, here's the cleanest solution I've found that doesn't rely on anything custom or external:
angular.module('yourModule')
.config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
$httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});
And then you can do this anywhere in your app:
$http({
method: 'POST',
url: '/requesturl',
data: {
param1: 'value1',
param2: 'value2'
}
});
And it will correctly serialize the data as param1=value1¶m2=value2 and send it to /requesturl with the application/x-www-form-urlencoded; charset=utf-8 Content-Type header as it's normally expected with POST requests on endpoints.
From AngularJS documentation:
params – {Object.} – Map of strings or objects which
will be turned to ?key1=value1&key2=value2 after the url. If the
value is not a string, it will be JSONified.
So, provide string as parameters. If you don't want that, then use transformations. Again, from the documentation:
To override these transformation locally, specify transform functions
as transformRequest and/or transformResponse properties of the config
object. To globally override the default transforms, override the
$httpProvider.defaults.transformRequest and
$httpProvider.defaults.transformResponse properties of the
$httpProvider.
Refer to documentation for more details.
Use jQuery's $.param function to serialize the JSON data in requestData.
In short, using similar code as yours:
$http.post("/foo/bar",
$.param(requestData),
{
headers:
{
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}
).success(
function(responseData) {
//do stuff with response
}
});
For using this, you have to include jQuery in your page along with AngularJS.
Note that as of Angular 1.4, you can serialize the form data without using jQuery.
In the app.js:
module.run(function($http, $httpParamSerializerJQLike) {
$http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});
Then in your controller:
$http({
method: 'POST',
url: myUrl',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: myData
});
This might be a bit of a hack, but I avoided the issue and converted the json into PHP's POST array on the server side:
$_POST = json_decode(file_get_contents('php://input'), true);
I have problems as well with setting custom http authentication because $resource cache the request.
To make it work you have to overwrite the existing headers by doing this
var transformRequest = function(data, headersGetter){
var headers = headersGetter();
headers['Authorization'] = 'WSSE profile="UsernameToken"';
headers['X-WSSE'] = 'UsernameToken ' + nonce
headers['Content-Type'] = 'application/json';
};
return $resource(
url,
{
},
{
query: {
method: 'POST',
url: apiURL + '/profile',
transformRequest: transformRequest,
params: {userId: '#userId'}
},
}
);
I hope I was able to help someone. It took me 3 days to figure this one out.
Modify the default headers:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
Then use JQuery's $.param method:
var payload = $.param({key: value});
$http.post(targetURL, payload);
.controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
var data = {
TimeStamp : "2016-04-25 12:50:00"
};
$http({
method: 'POST',
url: 'serverutilizationreport',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $httpParamSerializerJQLike(data),
}).success(function () {});
}
]);
Quick adjustment - for those of you having trouble with the global configuration of the transformRequest function, here's the snippet i'm using to get rid of the Cannot read property 'jquery' of undefined error:
$httpProvider.defaults.transformRequest = function(data) {
return data != undefined ? $.param(data) : null;
}
You can also solve this problem without changing code in server, changing header in $http.post call and use $_POST the regular way. Explained here: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
I found many times problematic behavior of this whole. I used it from express (without typings) and the bodyParser (with the dt~body-parser typings).
I didn't try to upload a file, instead simply to interpret a JSON given in a post string.
The request.body was simply an empty json ({}).
After a lot of investigation finally this worked for me:
import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!
It may be also important to give the application/json content type in the request string from the client side.
Syntax for AngularJS v1.4.8 + (v1.5.0)
$http.post(url, data, config)
.then(
function (response) {
// success callback
},
function (response) {
// failure callback
}
);
Eg:
var url = "http://example.com";
var data = {
"param1": "value1",
"param2": "value2",
"param3": "value3"
};
var config = {
headers: {
'Content-Type': "application/json"
}
};
$http.post(url, data, config)
.then(
function (response) {
// success callback
},
function (response) {
// failure callback
}
);