I am posting data to Dynamics CRM via SOAP on my PHP server with cURL. After this is done it is giving the entity GUID in the form of a HTTP Response header. When attempting to access this via my angular factory and $http.
My header is exposed and is able to be viewed in Chrome Developer tools and gives me the GUID I need.
The code for accessing the promise data is as follows:
$http({
method: 'POST',
url: url,
data: formData,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function (data, headers) {
var array = [];
array.data = data;
array.headers = headers('EntityId');
console.log(array.headers);
deferred.resolve(array);
})
return deferred.promise;
//etc
The error I get is:
headers is not a function()
I can however, access some header result such as a status 200 code by using:
array.headers = headers;
But I need to access my custom header. Any ideas on how I can achieve this?
As per Deprecation Notice on https://docs.angularjs.org/api/ng/service/$http
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.
the preferred way would be:
$http.get('/someUrl')
.then(function(response){
var array = [];
array.data = response.data;
array.headers = response.headers('EntityId');
});
As Andy said already, headers is the 3rd parameter of the success callback. So you will have to do this:-
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
})
I wasn't going to add this as an answer but doing this as I wanted to add that headers is indeed a function.
In my project, I did the below and saw function logged out as type in console. The function returns the value of the header item corresponding to the name passed, if no parameters are passed, returns an object containing all headers.
login(user) {
return this.$http.post(this.url, user)
.success((data, status, headers, config) => {
console.log(typeof headers, 'headers'); => prints function
console.log(headers(), 'headers'); => if you don't pass anything, returns an object containing all headers.
return response;
});
}
Excerpt from the angular code.
function headersGetter(headers) {
var headersObj;
return function(name) {
if (!headersObj) headersObj = parseHeaders(headers);
if (name) {
var value = headersObj[lowercase(name)];
if (value === void 0) {
value = null;
}
return value;
}
return headersObj;
};
You parameters for success are incorrect. headers is the third parameter.
$http.get('/someUrl').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Check "Usage" section in https://docs.angularjs.org/api/ng/service/$http for reference.
The $http service is a function which takes a single argument — a configuration object — that is used to generate an HTTP request and returns a promise.
The response object has these properties:
data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers –{function([headerName])} – Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.
Angular version == 1.3.5 , Suppose header value has been set "X-AUTH-TOKEN = 'eyJwYXNzd29yZCI6ImFkbWlu'" in Application Security class after authentication.
$scope.postData = "{\"username\" : username , \"password\": password ,\"email\" :email}";
$http({
method: 'POST',
url: '/API/authenticate',
data: postData,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Login-Ajax-call": 'true'
}
})
.then(function(response) {
if (response.data == 'ok') {
$cookies['X-AUTH-TOKEN']=response.headers('X-AUTH-TOKEN');
// below put,put,putObject Cookies value is valid for Angular version >= 1.4
// $cookies.putObject('X-AUTH-TOKEN',response.headers('X-AUTH-TOKEN');
window.location.replace('/');
}
else {
// Error Message...
}
});
Related
I have 3 files (HTML,JS and PHP) in the HTML save de info in variable called DatosPaciente in JavaScript
function Tomar_DATOS(){
DatosPaciente={
id:document.getElementById("paciente_id").value,
fecha:document.getElementById("fecha").value
};}
Then i use a function called Tiene_Cita_Hoy inside of a JS file
Tiene_Cita_Hoy(DatosPaciente)
in the JS file i try to use the Fetch API to send info to the PHP file
function Tiene_Cita_Hoy(Datos){
console.log(Datos);//"{id: "8", fecha: "2020/09/03"}" here everything is fine
fetch('tiene_cita.php',{
method: 'POST',
body: Datos
})
.then(res => res.json())
.then(data => {
console.log(data); //to see the result
})
}
then in a PHP file, then tried to receive the information via POST
$VALOR_id_paciente=$_POST['id'];
$VALOR_fecha=$_POST['fecha'];
and then I assign those values to a query
$SQL="SELECT * FROM vhsagenda WHERE PACIENTE='".$VALOR_id_paciente."' AND FECHA='".$VALOR_fecha."'";
echo json_encode($SQL);//just to see what information have
but the result is always: SELECT * FROM vhsagenda WHERE PACIENTE='' AND FECHA=''
apparently the information never reaches the PHP file
I have made some proper way for this method to get working.
You need to make an object first, then pass it in 'for loop'. It will generate string like this for example (test=123&test_two=444)
async function catch_something(url, bodyContent = {test: 123, test_two: 444}){
let bodyContent_string = '';
if(bodyContent instanceof Object){
for(const form_key of Object.keys(bodyContent)){
if(form_key != Object.keys(bodyContent)[Object.keys(bodyContent).length - 1]){
bodyContent_string += `${form_key}=${bodyContent[form_key]}&`;
}else{
bodyContent_string += `${form_key}=${bodyContent[form_key]}`;
}
}
}
const response = await fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: bodyContent_string
}).catch((error) => {
console.error('Error:', error);
});
if(!response.ok){
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
You should send the parameters as a URL-encoded string.
function Tomar_DATOS(){
DatosPaciente = 'id=' + encodeURIComponent(document.getElementById("paciente_id").value) + '&fecha=' + encodeURIComponent(document.getElementById("fecha").value);
}
You've passed a plain object to the body parameter, but fetch doesn't know what to do with that data type (so it converts it to the useless string "[object Object]").
You should pass something that fetch knows how to convert into something supported by PHP instead.
e.g. a FormData object.
DatosPaciente = new FormData(document.getElementById("form_containing_your_inputs"));
I have created an API which my AJAX post send values to it. AJAX does post and my laravel API does process the values. My issues is with the callback returning the value back to my AJAX post. My AJAX doesn't return the results in the success section when I do console log. I would like the results from my api to can use data to make my condition. At the moment, the console log doesn't even return a value. But in my chrome inspector under preview it shows the response from my API but not in the success section.
AJAX
var fname = "Joe";
var lname = "Test";
var processUrl = "api.example.com/z1";
$.ajax({
type: 'POST',
url: processUrl,
data: {"name": fname,"surname": lname},
dataType: 'json',
success: function(res){
console.log(res);
if(res.length >= 1){
$('#display').val(res.name);
}
}
});
PHP
public function checkResults(Request $request){
$name = $request->name." ".$request->surname;
$result = array();
$result['name'] = [$name];
return response()->json($result,201);
}
For first it will be good to return with 200 OK response code (instead of 201).
Note: If you want to just immediately get the answer for your question only, you can see the last part of this answer (usage of "done/fail" construct instead of "success/error").
Additional:
There is many patterns which are used by Client(Frontend)<->API<->Server(Backend) developers.
Approximately all APIs built without any 500 server error codes. But there is exists also many differences between APIs structures.
One of them is to send response like this (this is the only one example of response):
return response()->json([
'success' => true, // true or false
'message' => "Message about success!",
], 200); // 200, 401, 403, 404, 409, etc
The other approach is to always sending 200 OK, but message can be also about error:
return response()->json([
'success' => false, // true or false
'code' => 404,
'message' => "Resource not found!",
], 200);
This kind of methods will written under try{}catch() and will return only 200, but that messages can imitated also as an error (as in example).
The other (appropriate approach for you) is to change your Frontend AJAX functionality like this:
$.ajax({
type: 'POST',
url: processUrl,
data: {
{{--_token: "{{ csrf_token() }}",--}}
name: fname,
surname: lname
},
dataType: 'json'
}).done(function(res) {
console.log(res);
if(res.length >= 1) {
$('#display').val(res.name);
}
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("Error: " + textStatus);
});
AJAX .done() function replaces method .success() which was deprecated in jQuery 1.8. This is an alternative construct for the success callback function (like before: "success: function(){...}").
AJAX .fail() function replaces method .error() which was deprecated in jQuery 1.8. This is an alternative construct for the complete callback function (like before: "error: function(){...}").
Note: .error() callback is called on HTTP errors, but also if JSON parsing on the response fails. This is what's probably happening if response code is 200/201 but you still are thrown to error callback.
I believe this is happening because you are sending status code 201 (Created), but you need to send status code 200 (OK) to trigger the success callback.
public function checkResults(Request $request){
$name = $request->name." ".$request->surname;
$result = array();
$result['name'] = [$name];
return response()->json($result,200);
}
I couldn't find it specifically in the jQuery docs, but this SO question addresses it.
Due to the asynchronous nature of Ajax calls, do not put them in the normal execution flow of your program. See this post to get more insight.
A quick fix for your problem is to include the ajax call in a function and call that function anytime you want to interact with the server asynchronously.
var fname = "Joe";
var lname = "Test";
var processUrl = "api.example.com/z1";
ajaxCall();
function ajaxCall() {
$.ajax({
type: 'POST',
url: processUrl,
data: {"name": fname,"surname": lname},
dataType: 'json',
success: function(res){
console.log(res);
if(res.length >= 1){
$('#display').val(res.name);
}
},
error: function() {
console.log('error');
}
});
}
In addition, include an error function in the ajax call settings to handle cases where the ajax request fails. See this answer for alternative styles of doing this.
I'm trying to send a text that is typed via ajax to a php page that will make a query using that text that is received. I want to know how to send the value of variable nmClient to the php page. I tried the following code and the return was 500 (Internal Server Error). I'm using the framework Symfony
Jquery
var name = $("#name").val();
$.ajax({
url: "../search",
type: "POST",
data: {'name':name},
dataType: "json"
}).done(function(response) {
console.log(response);
}).fail(function(jqXHR, textStatus ) {
console.log("Request failed: " + textStatus);
}).always(function() {
console.log("done");
});
PHP
public function searchAction(Request $resquest)
{
if ($request->isXMLHttpRequest()) {
$name = $request->get('name');
return new JsonResponse(array('name' => $name));
}
return new Response('This is not ajax!', 400);
}
I believe you're trying to access the parameter name in the incorrect place. The get() method is available on the ParameterBag instance, not the Request instance. Try the following:
$name = $request->request->get('name');
Per the docs here:
Each property is a ParameterBag instance (or a sub-class of), which is a data holder class:
request: ParameterBag;
query: ParameterBag;
cookies: ParameterBag;
attributes: ParameterBag;
files: FileBag;
server: ServerBag;
headers: HeaderBag.
All ParameterBag instances have methods to retrieve and update their data:
get() Returns a parameter by name.
Here is the example from that same page:
// the query string is '?foo[bar]=baz'
$request->query->get('foo');
In the docs example case, the parameters are passed via the GET method as a query string but they access them via the query ParameterBag instance. You'll want to use the request Parameter Bag instance since your parameters are passed via the POST method.
I am trying to handle the push update in Angular in the view but it has been impossible for me. I know the following:
I have an array, this array is called marca1 and it receives all the objects that the get request that I make to the server and it shows in the view with ng-repeat.
When I send the post request to save a new data, it gets a response from the server that I save it in an object called pepa.
I use the push function for my fix to refresh the view, but that does not work.
Why can it be failing? How can I fix it?
This is my code:
miAppAngular.controller('marca',function($scope,$http,$location,$routeParams,configuracionGlobal){
$scope.config = configuracionGlobal;
$scope.marca1=[];
$http.get( configuracionGlobal.api_url + "/marca/listaMarca.php")
.then( function(respuesta){
$scope.marca1=respuesta.data;
});
$scope.nuevaMarca = function ( ){
$scope.newMarca={
'nombre':$scope.nombreMarca
}
$scope.pepa={};
//
$http({
url: configuracionGlobal.api_url + "/marca/nuevaMarca.php",
method: "POST",
data: $scope.newMarca,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(
function(respuesta){
$scope.pepa= respuesta;
$scope.marca1.push($scope.pepa);
$('#modalMarca').modal('hide');
}
)
}
Try to run getMarca after posting:
$scope.getMarca = function() {
$http.get( configuracionGlobal.api_url + "/marca/listaMarca.php")
.then(function(respuesta)
{
$scope.marca1=respuesta.data;
});
}
In your .then() of your post, at the end call: $scope.getMarca()
This shall update the array $scope.marca1.
The response returned after a POST is usually used for checking; whether it was a success or failure (or to return custom values from backend).
I am querying some server with AngularJS using $http.get
var onStuff = function(data) {
console.log( "Stuff received: " + angular.toJson(data));
$scope.stuff = data.data;
};
$http.get("https://some.server.net/stuff")
.then(onStuff, onError);
My back end is written in php and returns a properly formatted JSON.
I checked that loading https://some.server.net/stuff in a browser and testing by command line "php stuff.php" . It looks something like (truncated with ... to fit this screen):
[{"id":"1","user_id":"1","name":"Name1"},
{"id":"2","user_id":"1","name":"Name2"},
...
]
Please note this data is "unwrapped" or "just the array"
However, when onStuff() is invoked my array is "wrapped" inside another data object
Here is the console output
Stuff received:
{"data":[{"id":"1","user_id":"1","name":"Name1"},
{"id":"2","user_id":"1","name":"Name2"},...],
"status":200,
"config":{"method":"GET",
"transformRequest":[null],
"transformResponse":[null],
"url":"https://some.server.net/stuff",
"headers":{"Accept":"application/json, text/plain, */*"}},
"statusText":"OK"}
Here is the php stuff
<?
header('content-type: application/json; charset=utf-8');
header("access-control-allow-origin: *");
require_once("stuff.class.php");
$mysqli = new mysqli( "localhost", "user", "password", "database");
$list = Stuff::getList( $mysqli);
echo json_encode( $list);
$mysqli->close();
?>
I have been following a tutorial using github api, the JSON response was available directly in data
I am pretty sure this has to do with HTTP headers, but I hoped content-type would take care of it
What should I do to remove the unwanted "data" wrapper?
Instead of using the generic promise API (which seems to return an object with everything inside), use the success and error methods provided by $http:
var onStuff = function(data) {
console.log( "Stuff received: " + angular.toJson(data));
$scope.stuff = data.data;
};
$http.get("https://some.server.net/stuff")
.success(onStuff).error(onError);
That should gives you the data in the format you expect. The full API is as follow:
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
It seems like you expect onStuff to receive only the deserialized JSON data, but that's not what the API does. The object passed to your $http.get(...).then() callback (i.e. onStuff) is a response object with five properties: data, status, headers, config, and statusText--which is exactly what you're seeing in your console output. The data property has the deserialized JSON data, which is why you have to do $scope.stuff = data.data.
If you want onStuff to receive only the deserialized JSON data, you'll have to call it through an intermediary:
$http.get("https://example.com/stuff")
.then( function(response) {
onStuff(response.data);
} );