JavaScript code not checking ajax request properly - javascript

I have a case of the Thursdays and I am wondering why this isn't working.
The Problem: I cannot return the value of an array from AJAX request even though the page returns it successfully.
So, here's my AJAX request:
$.ajax({
type: "GET",
url: "get-sendgrid-info.php?username=" + emailToCheck,
success: function(dataSG) {
console.log("Length: " + dataSG.length + " Username: " + dataSG[0].username);
if (dataSG[0].username) {
console.log('CURRENTLY IN SEND GRID!');
$(".sgstatus").html("<div style='font-weight:bold;color:green;'>CURRENTLY IN SENDGRID</div>");
}else{
console.log('NOT IN SEND GRID!');
$(".sgstatus").html("<div style='font-weight:bold;color:red;'>NOT IN SENDGRID</div>");
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest);
console.log(errorThrown);
}
});
and that dataSG will call that php page:
if ($email) echo json_encode($data);
}
$stmt->close();
$mysqli->close();
which will output something like this:
Array
(
[0] => stdClass Object
(
[username] => sample#email.net
[email] => sample#email.net
[active] => true
[first_name] => John
[last_name] => Doe
[address] => 123 Fake Street
[address2] => Suite117
[city] => Denver
[state] => CO
[zip] => 12345
[country] => US
[phone] => 555-555-5555
[website] => http://website.com
[website_access] => true
)
)
1
(yes, even that 1).
So, when I try this after the AJAX request
if (dataSG[0].username) {
console.log('CURRENTLY IN SEND GRID!');
$(".sgstatus").html("<div style='font-weight:bold;color:green;'>CURRENTLY IN SENDGRID</div>");
}else{
console.log('NOT IN SEND GRID!');
$(".sgstatus").html("<div style='font-weight:bold;color:red;'>NOT IN SENDGRID</div>");
}
I always get NOT IN SENDGRID even though the response shows an array with a username clearly in it.
Help, please?
edit: I should add that I am on a IIS server.
edit: Response console says:
Object {readyState: 4, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}abort:
...
Object
create-email.php:2629 SyntaxError: Unexpected token A {stack: (...), message: "Unexpected token A"}message: "Unexpected token A"stack: (...)get stack: function () { [native code] }set stack: function () { [native code] }__proto__: Error

I think the reason is that your pho script is echoing the string start with "Array". The Ajax .get method does a smart guess for return object. When it receive a string from php, it could not convert it into either Jason nor xml so it think the dataSG is simply string. The Json_encode did not do it successfully. You have to format your php output to be something like "['a','b']", then Ajax can successfully convert it into a JavaScript array.

Try this:
...
success: function(dataSG) {
dataSG = JSON.parse(dataSG);
...

Related

Cypress POST request, how to access 'fields' section of reponse body

I want to send a POST request in Cypress that triggers the validation to reject the request
According to Postman, the body of the response looke like this:
"code": "validation_error",
"message": "Validation error, please see fields property for details",
"fields":
{
"TariffData[rate_gp]": " Invalid rate_gp. Expected: 9.35. Imported: 19.35"
}
I am interested in the "fields" section, so I tried to assert with this code:
const api_key = require('../../fixtures/contracts/api_test_client1.json')
const body1 = require('../../fixtures/contracts/body_test_client1.json')
describe('test POST/client validation', () => {
it('send POST/client request', function () {
cy.request({
method: 'POST',
url: Cypress.env('staging_url') + '/service/clients',
headers: {
'API-KEY': api_key,
},
body: body1,
failOnStatusCode:false
})
.then(response => {
expect(response.status).to.eq(400)
expect(response.body.fields).to.contain('"TariffData[rate_gp]": " Invalid rate_gp. Expected: 9.35. Imported: 19.35"')
})
)}
)}
Yet this leads to an error:
AssertionError
object tested must be an array, a map, an object, a set, a string, or a weakset, but object given
Yes, the error message ends there. Any ideas how I can make an assertion that the response contains this message?
I think you just want to present the expected value as an object, not as a string
expect(response.body.fields)
.to.contain({
"TariffData[rate_gp]": " Invalid rate_gp. Expected: 9.35. Imported: 19.35"
})
If you looks at the docs chaijs API they show, for example
expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
and contain is a synonym for include
You could also try to.deep.equal, as it seems you are specifying the total fields property
expect(response.body.fields)
.to.deep.eq({
"TariffData[rate_gp]": " Invalid rate_gp. Expected: 9.35. Imported: 19.35"
})

PayPal Smart Payment Buttons: Error: JSON.parse: unexpected character at line 1 column 1 of the JSON data

I've been trying to figure out this problem for 2 days already..
I want to implement Smart Payment Buttons from PayPal, literally followed every step of the explanation closely but still getting following error:
Error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
My javascript for Button rendering:
paypal.Buttons({
createOrder: function() {
return fetch('vendor/paypal/paypal-checkout-sdk/samples/CaptureIntentExamples/CreateOrder.php', {
method: 'post',
headers: {
'content-type': 'application/json'
}
}).then(function(res) {
return res.json();
}).then(function(data) {
return data.orderID; // Use the same key name for order ID on the client and server
});
},
onApprove: function(data, actions) {
// This function captures the funds from the transaction.
return actions.order.capture().then(function(details) {
// This function shows a transaction success message to your buyer.
alert('Transaction completed by ' + details.payer.name.given_name);
});
},
onError: function(err) {
alert(err);
}
}).render('#paypal-button-container');
My CreateOrder.php:
namespace Sample\CaptureIntentExamples;
require __DIR__ . '/../../../../autoload.php';
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
class CreateOrder
{
/**
* Setting up the JSON request body for creating the Order. The Intent in the
* request body should be set as "CAPTURE" for capture intent flow.
*
*/
private static function buildRequestBody()
{
return array(
'intent' => 'CAPTURE',
'application_context' =>
array(
'return_url' => 'https://example.com/return',
'cancel_url' => 'https://example.com/cancel'
),
'purchase_units' =>
array(
0 =>
array(
'amount' =>
array(
'currency_code' => 'USD',
'value' => '220.00'
)
)
)
);
}
/**
* This is the sample function which can be sued to create an order. It uses the
* JSON body returned by buildRequestBody() to create an new Order.
*/
public static function createOrder($debug=false)
{
$request = new OrdersCreateRequest();
$request->headers["prefer"] = "return=representation";
$request->body = self::buildRequestBody();
$client = PayPalClient::client();
$response = $client->execute($request);
if ($debug)
{
print "Status Code: {$response->statusCode}\n";
print "Status: {$response->result->status}\n";
print "Order ID: {$response->result->id}\n";
print "Intent: {$response->result->intent}\n";
print "Links:\n";
foreach($response->result->links as $link)
{
print "\t{$link->rel}: {$link->href}\tCall Type: {$link->method}\n";
}
// To toggle printing the whole response body comment/uncomment below line
echo json_encode($response->result, JSON_PRETTY_PRINT), "\n";
}
return $response;
}
}
if (!count(debug_backtrace()))
{
CreateOrder::createOrder(true);
}
It's basicly all copied from the PayPal walkthough.
If I visit the CreateOrder.php directly it is creating an order and I can see the response without errors.
Status Code: 201 Status: CREATED [...]
What I did was deleting the part of the code which was printing out the response in txt format. This is why you were getting JSON syntax error.
public static function createOrder($debug=false)
{
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = self::buildRequestBody();
// 3. Call PayPal to set up a transaction
$client = PayPalClient::client();
$response = $client->execute($request);
// To print the whole response body, uncomment the following line
echo json_encode($response->result, JSON_PRETTY_PRINT);
// 4. Return a successful response to the client.
return $response;
}
By the way, this answer is very helpful: https://stackoverflow.com/a/63019280/12208549

Unable to customize form errors because server is returning 422 Unprocessable Entity without returning errors

I'm working with Laravel and VueJS and for all of my post and put methods server returns the newly created data after submitting the form, in the case of errors, I cannot access them from the browser console. This is what I can see in the newtwork tab.The purpose is to customize form errors according to errors that is being returned by the server
Here is my backend code :
private function validateForm($data){
return Validator::make($data,
[
'fname' => ['required', 'string','min:2' ,'max:255'],
'lname' => ['required', 'string','min:2' ,'max:255'],
// 'mname' => ['string','min:2' ,'max:255'],
'company' => ['string','min:2' ,'max:255'],
'title' => ['string','min:2' ,'max:255'],
'phone_number' => ['string','min:13' ,'max:13'],
'city' => ['required', 'string','min:2' ,'max:100'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed']
// 'password_confirm'=>['required','string']
]
)->validate();
}
//Register
public function register(Request $request){
$data=$this->validateForm($request->all());
$data['password']=Hash::make($data['password']);
$user=new User($data);
$user->save();
return response()->json($user);
}
And my code from the front-end:
export default{
data(){
return {
form:{
email:'',
password:'',
password_confirmation:'',
fname:'',
lname:'',
city:''
},
formError:''
}
},
methods:{
//This should be a POST method through axios
register:async function(){
try{
const res=await axios.post('api/register',
{
email:this.form.email,
password:this.form.password,
password_confirmation:this.form.password_confirmation,
fname:this.form.fname,
lname:this.form.lname,
city:this.form.city
});
//Une fois inscrit,il est redirige vers la page de login
this.$router.push({path:'/login'});
console.log("My data : ",res.data);
}catch(err){
console.log("Errors",err);
}
}
}
}
When there are no errors, everything goes fine, but when there are errors, this is what I get in the browser console tab:
And in the Devtools network tab
I've tried the following link Issues with Axios catch method from Laracast
how to display the errors in .catch coming from an api on frontend
And some others solution,but all of them didn't solve my problem.
Before using async-await pattern i used axios.post('url',data).then(res=>...).catch(err=>...)
When i use postman,http status is still 422 but the error object is returned,so with postman everything goes fine but not in the browser
How can i solve this problem?
Laravel returns the HTTP 422 - Unprocessable Entity when the validations you set fail. In your case I would take a closer look at the data you're posting to the server and manually check if it passes the validation cases you wrote.
To get the exact fields that are causing the error you need to handle this in your code, like this for example:
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
// 500 is the HTTP Status Code you want to return.
// This should also throw you in the catch branch of your front-end code
return response()->json(['errors'=>$validator->errors()], 500);
}
In your code the $data variable from the register function should be checked if it fails validation and return the error
This is because err will return the toString() method when accessed directly, but has properties:
err.response.data will have what you're looking for.
When there's an HTTP error (e.g. a response code between 400 and 599) axios returns an axios error response and in the repository documentation under error handling it indicates that you can access the actual response using error.response.data. For example:
try {
const res=await axios.post('api/register',
{
email:this.form.email,
password:this.form.password,
password_confirmation:this.form.password_confirmation,
fname:this.form.fname,
lname:this.form.lname,
city:this.form.city
});
//Une fois inscrit,il est redirige vers la page de login
this.$router.push({path:'/login'});
console.log("My data : ",res.data);
}catch(err){
if (err.response && err.response.status === 422) {
if (err.response.data.errors.fname) {
console.log('First name errors: '+ err.response.data.errors.fname.join(','));
}
// and so on
}
}
When Axios throws an error, the HTTP response can be found in error.response. Validation errors will be in the errors key, so you can access validation errors like this:
axios.post(someUrl, someData)
.then(response => {
// Successful response
})
.catch(error => {
let errors = error.response.data.errors;
});

json content in response object in javascript returned from service worker

Sorry if trivial, or already asked, I can't find any question about that. I dont't know if I'doing right too...
I just beginned learning service workers:
I'd like to return some json object from a service worker for a specific request. N.B.: The code is just testing/learning code:
Service Worker Fetching Event:
self.addEventListener('fetch', function(event) {
if(event.request.url.indexOf("not_existing.json") > -1){
var obj = { "Prop" : "Some value" };
event.respondWith(
new Response(obj, {
ok: true,
status: 222,
url: '/'
})
);
}});
Fetch Call:
fetch('not_existing.json')
.then(function(responseObj) {
console.log('status: ', responseObj.status);
return responseObj.json();
})
.then(function (data){
console.log(data);
});
I know that the service worker catches the request, because on "console.log('status: ', responseObj.status);" I get "222", but the script breaks on "return responseObj.json();" with error "Uncaught (in promise) SyntaxError: Unexpected token o in JSON at position 1"
If I return "plain text" from service worker, and read it with "responseObj.text()" all works great!
On this link "https://developer.mozilla.org/en-US/docs/Web/API/Response/Response" it seems I have only to write the body on Response constructor var myResponse = new Response(body, init);
What's wrong? How to specify the json response object?
You're not actually creating a response with JSON. The first argument of Response is a string or a few others, but not a random object. If you want JSON, you need to actually pass JSON, e.g.
var obj = JSON.stringify({ "Prop" : "Some value" });
The error you are getting is because currently it is converted to a string as
"[object Object]"
and
JSON.parse("[object Object]")
throws unexpected token "o".

Why does axios always send empty object?

I'm trying to figure this out and it's driving me mad. I am trying to send an object of data using an axios post request. It goes to the file okay but the object is always empty. So when I use this code:
axios.post('php/send_email.php', {
params: {
name: 'niall'
}
})
.then(function (result) {
console.log(result)
});
And then use the php below:
<?php
echo $_POST['name'];
?>
It will always output an error of name being undefined for the result from the http request.Can anyone shed some light on this and where I am going wrong?
Also I noticed that this seems to be a problem with sending an object because when I try:
axios.post('php/send_email.php', 'niall' )
.then(function (result) {
console.log(result)
});
And then print out the array using:
<?php
print_r($_POST);
?>
It will show:
Object {data: "Array↵(↵ [niall] => ↵)↵", status: 200, statusText: "OK", headers: Object, config: Object…}
Try sending like this
axios.post('php/send_email.php', { name: 'niall' }})
instead of wrapping parameters in an extra params object.

Categories

Resources