Using ajax in Servant - ajax

I use Haskell with servant-0.7.1 fo realisation server.Below is my source code:
type UserRestAPI
= "rest" :> "users" :> Get '[JSON] [User]
:<|> "rest" :> "user" :> ReqBody '[JSON] User :> Post '[PlainText] Text
serverUserRestAPI :: ServerT UserRestAPI AppM
serverUserRestAPI = usersGet :<|> userPost
userPost :: User -> AppM Text
userPost user = do
newUser <- runDb $ do insert user
liftIO $ putStrLn $ show newUser
return $ append (toPathPiece newUser) "\r\n"
The model of User:
let mongoSettings = (mkPersistSettings (ConT ''MongoContext)) {mpsGeneric = False}
in share [mkPersist mongoSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
fam String
im String
ot String
email String
login String
pswd String
deriving Show
|]
$(deriveJSON defaultOptions ''User)
For testin curl was used, as shown below.
curl --verbose --request POST --header "Content-Type: application/json" \
--data '{"userFam": "Fam", "userIm": "Im", "userOt": "Ot", "userEmail": "mail#mail.ru", "userLogin": "test", "userPswd": "test"}' \
http://127.0.0.1:3000/rest/user
Everything is working. The data added to the database.But when I use ajax from backend, as shown below.
var formElement = $("#id_form");
var formData = formElement.serializeArray();
var objectData = {};
for(var i = 0; i < formData.length; i++)
objectData[formData[i].name] = formData[i].value;
$.ajax({
type: "POST",
async: true,
url: "/rest/user",
dataType: "text",
cache : false,
contentType : "application/json",
data: objectData,
success: function(result){
consoloe.log(result)
},
error: function(jqXHR, status, err) {
console.log(err)
}
});
I get an error!
jquery.js:4 POST http://127.0.0.1:3000/rest/user 400 (Bad Request)
The debugger checked object objectData. All right (Object {userFam: "qqq", userIm: "www", userOt: "eee", userEmail: "rrr", userLogin: "ttt"…}).
I can not understand what was going on.

it's really a problem with your ajax call as you don't provide a valid JSON object but just objectData.toString() as data: - the common solution is to use JSON.stringify:
$.ajax({
type: "POST",
async: true,
url: "/rest/user",
dataType: "json",
cache : false,
data: JSON.stringify(objectData),
success: function(result){
// ...
},
error: function(jqXHR, status, err) {
console.log(err)
}
});
another great example what is wrong with untyped languages ;)

Related

Shopify Ajax API

I am trying to access the Shopify backend to update a customer's email, phone, and name via Ajax request.
I'm receiving a 404 error. while in postman and in google chrome the values are returned correctly and in postman, I am able to modify the values with PUT type.
my code:
let custFN = document.getElementById("customerFirstName").getAttribute("value") ;
let custLN = document.getElementById("customerLarstName").getAttribute("value") ;
let custEM = document.getElementById("customerEmail").getAttribute("value") ;
let custPH = document.getElementById("customerPhone").getAttribute("value") ;
let custID = document.getElementById("customerId").getAttribute("value") ;
let customerdata = {
"customer": {
"id": custID,
"first_name": custFN ,
"last_name": custLN,
"email": custEM,
"phone": custPH,
}
};
var customer_data_json = JSON.stringify(customerdata);
jQuery.cookie("session", null);
jQuery.ajax({
url:'https://{api key}:{api password}#{mysotre}.myshopify.com/admin/api/2022-04/customers/{customer_id}}.json',
type: 'PUT',
cache: false,
data: customer_data_json,
crossDomain: true,
dataType: "JSONP",
contentType: "application/json; charset=utf-8",
success: function(response) {
console.log(response);
},
error: function(response) {
console.log("-------------------------------- <ERROR> --------------------------------");
console.log(response);
console.log("-------------------------------- </ERROR> --------------------------------");
}
});
I placed the values noted with {} above.
I have changed to JSONP from JSON to avoid and fix the CORS policy error.
keep in mind that the response readyState is 4.
P.S: As mentioned by Shopify documentation, I created a private app, and did all the steps required to CRUD using API in Shopify are done.

Why is my ajax having a validation error querying yelp api?

First question here, so please forgive me if I don't ask it correctly.
I have the following code:
function getMapPlaces() {
var key =
"_961jkjpPEKGMX6YlEZm8awCLH1avefv5RUIhm6ciV_8kfRRr-gRay5GIICt9Ih-ggqoKNJdnSD7rBuIwmcbiaHSLUFWeJmOaHmzO5t4UwYvJCfX7hy38gy4IhUWX3Yx;";
var settings = {
async: true,
crossDomain: true,
url:
"https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search",
method: "GET",
headers: {
Authorization: "Bearer " + key,
//"x-rapidapi-host": "YelpAPIserg-osipchukV1.p.rapidapi.com",
//"x-rapidapi-key": "629a103ae7msh8d2e000534865ffp18dc6ejsna10a77d719b1",
//"content-type": "application/x-www-form-urlencoded",
},
data: {
location: "Harrisburg",
accessToken:
"_961jkjpPEKGMX6YlEZm8awCLH1avefv5RUIhm6ciV_8kfRRr-gRay5GIICt9Ih-ggqoKNJdnSD7rBuIwmcbiaHSLUFWeJmOaHmzO5t4UwYvJCfX7hy38gy4IhUWX3Yx",
},
};
$.ajax(settings).done(function (response) {
console.log(response);
});
}
getMapPlaces();
But am getting the following error:
{error: {code: "VALIDATION_ERROR",…}}
error: {code: "VALIDATION_ERROR",…}
code: "VALIDATION_ERROR"
description: "'Bearer ;' does not match '^(?i)Bearer [A-Za-z0-9\-\_]{128}$'"
field: "Authorization"
instance: "Bearer ;"
with my api key replacing . What am I doing wrong here?
Try removing semicolon (;) at the end of your key value (the last character in the string).
The regex ([A-Za-z0-9\-\_]{128}$) error seems self explanatory.
Your authorization header does not match the regular expression they provide for validation. See for yourself:
var key = "_961jkjpPEKGMX6YlEZm8awCLH1avefv5RUIhm6ciV_8kfRRr-gRay5GIICt9Ih-ggqoKNJdnSD7rBuIwmcbiaHSLUFWeJmOaHmzO5t4UwYvJCfX7hy38gy4IhUWX3Yx;";
var authorizationHeader = "Bearer " + key;
var validator = new RegExp('^Bearer [A-Za-z0-9\-\_]{128}$');
authorizationHeader.match(validator);

Laravel 5.4 not able to parse FormData javascript object sent using Jquery Ajax

Lately I've been trying to solve an issue with no luck, basically I'm trying to submit a form to the server using AJAX, the form has files, so I'm using the FormData javascript object in JQuery 1.12. The data arrives to the server but in I way I don't know how to format it.
This is my AJAX function:
function saveMenu(id){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_method', 'PUT');
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
$.ajax({
type: 'PUT',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{url('myUrl')}}",
data: formData,
enctype: 'multipart/form-data',
processData: false,
success: function(response) {
toastr.success('Yai! Saved successfully!')
},
error: function(response) {
toastr.error('Oh oh! Something went really wrong!')
},
complete: function() {
$( "#form-wrapper" ).toggleClass( "be-loading-active" )
}
});
}
and when I perform a dd($request->all()); in my controller I get something like this:
array:1 [
"------WebKitFormBoundaryRCIAg1VylATQGx46\r\nContent-Disposition:_form-data;_name" => """
"_token"\r\n
\r\n
jtv4bnn8WQnP3eqmKZV3xWka2YOpnNc1pgrIfk0D\r\n
------WebKitFormBoundaryRCIAg1VylATQGx46\r\n
Content-Disposition: form-data; name="blocks[43][title]"\r\n
\r\n
...
Things I've tried:
Set the HTTP verb to POST. Same result.
Set the AJAX contentType: false, contentType: application/json. Empty response.
Remove enctype: 'multipart/form-data'. Same response.
Any help is appreciated.
This fixed it for me
data: form_data,
contentType: false,
processData: false,
processData: false prevents jQuery from parsing the data and throwing an Illegal Invocation error. JQuery does this when it encounters a file in the form and can not convert it to string (serialize it).
contentType: false prevents ajax sending the content type header. The content type header make Laravel handel the FormData Object as some serialized string.
setting both to false made it work for me.
I hope this helps.
$('#my-form').submit(function(e) {
e.preventDefault();
var api_token = $('meta[name="api-token"]').attr('content');
form_data = new FormData(this);
$.ajax({
type: 'POST',
url: '/api/v1/item/add',
headers: {
Authorization: 'Bearer ' + api_token
},
data: form_data,
contentType: false,
processData: false,
success: function(result,status,xhr) {
console.log(result);
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
also remember to use $request->all(); $request->input() excludes the files
I've been trying to debug that for 2 hours and i found out that method PUT is not working with formData properly.
Try changing
type : "PUT"
into
method : "POST"
Then change your method on your backend from put to post and you'll see the difference.
I used below codes to test it
$("#menu-form").submit(function (){
var fd = new FormData();
fd.append('section', 'general');
fd.append('action', 'previewImg');
fd.append('new_image', $('.new_image')[0].files[0]);
$.ajax({
method : 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token()}}'
},
url: "{{url('upload-now')}}",
data : fd,
contentType: false,
processData: false,
success: function(response) {
console.log(response);
},
});
return false;
});
And in my controller
public function test(Request $request){
dd($request->all());
}
Ill try to research more about this issue.
Laravel 7,
if use method PUT in ajax, you can follow
1. change method method: 'PUT' to method: 'POST'
2. add formdata.append with _method PUT like this example :
$('#updateBtn').click(function(e){
e.preventDefault();
var frm = $('#tambahForm');
frm.trigger("reset");
$('.edit_errorNama_kategori').hide();
$('.edit_errorGambar').hide();
var url = "/pengurus/category/"+$('#edit_id').val();
var formdata = new FormData($("#editForm")[0]);
formdata.append('_method', 'PUT'); //*** here
$.ajax({
method :'POST', //*** here
url : url,
data : formdata,
dataType : 'json',
processData: false,
contentType: false,
success:function(data){
if (data.errors) {
if (data.errors.nama_kategori) {
$('.edit_errorNama_kategori').show();
$('.edit_errorNama_kategori').text(data.errors.nama_kategori);
}
if (data.errors.gambar){
$('.edit_errorGambar').show();
$('.edit_errorGambar').text(data.errors.gambar);
}
}else {
frm.trigger('reset');
$('#editModal').modal('hide');
swal('Success!','Data Updated Successfully','success');
table.ajax.reload(null,false);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Please Reload to read Ajax');
console.log("ERROR : ", e);
}
});
});
its works for me
Finally I gave up trying to make it work and tried a more vanilla approach, I still don't know the reason why the request is formated like that, but the XMLHttpRequest() function works perfectly and the migration is not a big deal.
The equivalent of the function I posted about would be:
function saveMenu(action){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_token', $('meta[name="csrf-token"]').attr('content'));
var request = new XMLHttpRequest();
request.open("POST", "{{url('myUrl')}}");
request.send(formData);
request.onload = function(oEvent) {
    if (request.status == 200) {
      toastr.success('Yai! Saved successfully!');
    } else {
      toastr.error('Oh oh! Something went really wrong!');
}
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
  };
}
Bit late, but;
This will solve your problem;
var formData = new FormData(document.getElementById('form'));
console.log(...formData);
var object = {};
formData.forEach(function (value, key) {
object[key] = value;
});
Then you can send this object to the server. This is much more readable and works great.
OR
You can simply send this directly;
JSON.stringify(Object.fromEntries(formData));
This is the newer approach.
And don't give up :-)

JSON Broken on Display

I have a JSON File, giving by vendor
{"html": "\n<link href=\"//apply.fundingoptions.com/static/msmclone/css/oembed-v3.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\">\n var __raconfig = __raconfig || {};\n __raconfig.uid = '53302e56328ff';\n __raconfig.action = 'track';\n (function () {\n var ra = document.createElement('script');\n ra.type = 'text/javascript';\n ra.src = ('https:'==document.location.protocol?'https://':'http://')\n +'www.ruleranalytics.com/lib/1.0/ra-bootstrap.min.js';\n var s = document.getElementsByTagName('script')[0];\n s.parentNode.insertBefore(ra, s);\n }());\n</script>\n\n<div id=\"oembed-widget-container\" class=\"oembed-widget-container\">\n <div class=\"callout\">Initialising Finance Finder...</div>\n</div>\n<script type=\"text/javascript\">\n \n var widget_affiliate_id = 10;\n \n \n var widget_continue_url = \"//apply.fundingoptions.com/continue/\";\n \n \n var widget_submission_url = \"//apply.fundingoptions.com/oembed/submit/\";\n \n \n var widget_match_url = \"//apply.fundingoptions.com/match/\";\n \n \n var widget_title = \"Your funding options\";\n \n</script>\n<script src=\"//apply.fundingoptions.com/static/oembed/oembed-v4.js\"></script>\n\n",
"title": "Funding Options Finance Finder",
"version": 0,
"type": "rich",
"width": 500,
"height": 400
}
and I am parsing it on a webpage using this method
$.ajax({
type: 'GET',
url: 'json/data.json',
data: { get_param: 'value' },
dataType:'json',
success: function (data) {
var names = data
$('#summary').html(data.html);
}
});
But in the end , its show something like that on webpage:
as I am implementing it first time , I am not sure its my bad or json is corrupt or what else.
Looks like this is a Cross Origin Resource Sharing issue.
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Check your browser console and look at the error you are getting when you try to load the page. It should say something similar to:
XMLHttpRequest cannot load http://apply.fundingoptions.com/match/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Because the data you are requesting is not on the same server as you you are being denied access.
It looks like the error is happening when the following request is made in the oembed-v4.js library:
jQuery.ajax({
url: that.match_url,
type: 'POST',
data: postData,
success: function(data, textStatus, jqXHR) {
that.data = data;
if (data['next_question'] == null) {
that.showActions();
that.$spinnerElement.removeClass('fa-cog');
that.$spinnerElement.addClass('fa-check');
} else {
that.drawQuestion();
}
},
error: function(jqXHR, textStatus, errorThrown) {
that.displayError();
},
complete: function() {
that.toggleSpinner(false);
}
});
The vendor may need to enable Cross Origin Resource Sharing on their end from your domain.
Here is a working example of the jQuery Ajax call:
$.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1',
dataType:'json',
success: function (resp) {
console.log(resp)
var names = resp.title
$('#summary').html(names);
},
error: function (resp) {
console.log('error')
}
});
You can edit this to match your data. Make sure that the url is correct, you can try:
'./json/data.json'
You JSON is parsed correctly according to: https://jsonlint.com/
So it must be the URL.

Posting JSON with AJAX request in play2

i'm using play framework 2.0.4
i have a route :
POST /addMail controllers.Application.addMail()
In my controller Application i define the addMail method :
public static Result addMail()
{
JsonNode json = request().body().asJson();
Long id = json.findPath("id").asLong(0);
String email = json.findPath("email").getTextValue();
GameScore gs = GameScore.findById(id);
gs.setEmail(email);
gs.save();
return ok();
}
If i call this method through CURL i have no problem :
curl --header "Content-type: application/json" --request POST --data '{"id": 13, "email": "test#DB.com"}' http://localhost:9000/addMail
But if i call this method through an AJX request i have a 500 response.
$addMailBtn.click(function(event) {
$this = $(this);
var id = $this.attr("id").substring(14);
var email = $("#saisieMailField_" + id).val();
$.ajax({
type: 'POST',
url: "#routes.Application.addMail()",
dataType:"json",
data: {"id":id, "email": '"' + email + '"'},
success: location.reload()
})
} );
If i print in my console my json data, json data is null when i perform my ajax request but is alright through curl.
I have tried to add
#BodyParser.Of(play.mvc.BodyParser.Json.class)
on my method but it doesn't change anything.
Thanks for your time.
This works for me. Note that i stringify the JSON object, and I think this is your problem.
$.ajax({
type: "POST",
url: "http://myservice:9000/api/v1/positions",
data: JSON.stringify({"nwLng":72.22,"nwLat":22.22, "seLng":22.22,"seLat":55.33}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) { alert(data); },
failure: function (errMsg) { alert(errMsg); }
});

Resources