jQuery.getJSON equivalent in MooTools - ajax

Is there any jQuery.getJSON() equivalent in MooTools? I have a json file named data.json and I want to get its content by calling data.json file using MooTool. Is it possible? I tried Request.JSON() method but it didn't work for me. The below is my code,
var json_req = new Request.JSON({
url:'../public_html/data/data.json',
method: 'get',
secure: true,
data:{
json: true
},
onSuccess: function (res){
this.result = res;
},
onFailure: function(){
this.result = "failed";
}
}).send();
Also from the http://demos111.mootools.net/ I found an Ajax class named Ajax() which they are widely using through out their tutorial. But in MooTools documentation I didn't find this Ajax() class. I tried to use the Ajax() by replacing my Request.JSON(), but got an "Ajax not defined" error. What is this Ajax class and how can we use it in MooTools?

Here is a simple example of the functionality you are looking after. Basically wrapping a function around the Class... you could use the Class directly also.
function getJSON(url, callback) {
new Request.JSON({
url: url,
onSuccess: callback
}).send();
}
// and invoque it:
getJSON('/echo/json/', function(json) {
console.log(json);
});
you can check it live here: https://jsfiddle.net/w64vo2vm/

This one works for me
window.addEvent('domready', function() {
new Request.JSON({
url: url,
data: {'delay': 1},
method: 'post',
onSuccess: function(response) {
var myJSON = JSON.encode(response)
console.log(myJSON);
}
}).send();
})
You may see the result here
http://jsfiddle.net/chetabahana/qbx9b5pm/

I have a small function for this task. Here's the code
var configJson;
function klak_readJson(fileurl) {
var myRequest = new Request({
url: fileurl,
method: 'get',
onRequest: function(){
console.log('loading '+fileurl+'...');
},
onSuccess: function(responseText) {
console.log('received bytes '+responseText.length);
configJson=JSON.parse(myRequest.response.text);
}
});
myRequest.send();
}
Call the function to store the JSON object into configJson
klak_readJson('/js/test.json');
Hope it helps.

Related

call function in ajax success callback

Is it possible to call a function in success callback of ajax request?
For example I have something like that :
constructor(private http: HttpClient,private serviceComposition: CompositionService) { }
[...]
save() {
var isValid = this.isValidCompo();
if (true) {
var toSend = JSON.stringify(this.setupComposition);
$.ajax({
url: "/api/setup/composition/addSetupComposition",
type: 'POST',
dataType: "json",
data: 'setupComposition=' + toSend,
success:function(response){
//console.log("Success Save Composition");
},
error: function(XMLHttpRequest,textStatus,errorThrown){
console.log("Error Save Compo");
}
}).done(function(data){
this.serviceComposition.changeValue(isValid);
})
}
}
I want to call a function of my service (named : changeValue() ) if my ajax request is a success.
But I have this error message : core.js:12632 ERROR TypeError: Cannot read property 'changeValue' of undefined
Do you know if it's possible to resolve that ?
I am suspecting this binding is going wrong in call backs,
prefer using arrow function because of "this" operator binding.
if (true) {
var toSend = JSON.stringify(this.setupComposition);
$.ajax({
url: "/api/setup/composition/addSetupComposition",
type: 'POST',
dataType: "json",
data: 'setupComposition=' + toSend,
success:function(response){
//console.log("Success Save Composition");
},
error: function(XMLHttpRequest,textStatus,errorThrown){
console.log("Error Save Compo");
}
}).done((data) => {
this.serviceComposition.changeValue(isValid);
})
}
if not u can store this reference in a variable and call it
var self = this;
if (true) {
var toSend = JSON.stringify(this.setupComposition);
$.ajax({
url: "/api/setup/composition/addSetupComposition",
type: 'POST',
dataType: "json",
data: 'setupComposition=' + toSend,
success:function(response){
//console.log("Success Save Composition");
},
error: function(XMLHttpRequest,textStatus,errorThrown){
console.log("Error Save Compo");
}
}).done(function(data){
self.serviceComposition.changeValue(isValid);
})
}
Use an arrow function to access this of your parent scope. In your example, this is referring to your jQuery XHR object.
So:
// [parent scope]
$.ajax({
...
}).done((data) => {
// [child scope]
// `this` now refers to [parent scope], so the following is valid
this.serviceComposition.changeValue(isValid);
});
Another common practice prior to arrow functions (ES6) would've been assigning a const self = this; variable in the [parent scope] area to be accessed in the child method. Either method works the same.
Also check out the MDN docs on this. It's a confusing topic for many.

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 :-)

Can Js and Model.findAll() unable to display data in UI

I have this code where i am trying to retrieve data from model.findall() and display in UI as table
model.js
define(['jquery', 'can'], function ($, can) {
var serviceModel = can.Model.extend({
findAll: function (params,servicename) {
return $.ajax({
type: 'POST',
dataType: 'JSON',
contentType: 'application/json',
url: 'data/+ servicename',
success: function (data) {
console.log("Success ");
},
error: function () {
console.log("Error");
}
});
}
}, {});
return serviceModel;
});
controller.js
serviceModel.findAll(params,"SP_table", function(data) {
if (data.status === "success") {
$('#idtable').dataTable().fnClearTable();
$('#idtable').dataTable().fnAddData(data.result);
}else{
alert("inside alert");
}
});
issue is in serviceModel.findAll() i am unable to get data inside serviceModel.findAll() because data is in the form of stored procedure or macro, which i am getting using "servicename" from function above
please let me know how to resolve this issue.
You can access the raw xhr data from the ajax call and convert it to an appropriate format by overriding the parseModels method:
https://canjs.com/docs/can.Model.parseModels.html
Overwriting parseModels If your service returns data like:
{ thingsToDo: [{name: "dishes", id: 5}] } You will want to overwrite
parseModels to pass the models what it expects like:
Task = can.Model.extend({ parseModels: function(data){ return
data.thingsToDo; } },{}); You could also do this like:
Task = can.Model.extend({ parseModels: "thingsToDo" },{});
can.Model.models passes each instance's data to can.Model.model to
create the individual instances.
In their example above, the response is a nested JSON: in yours, it is your procedure or macro. You have the opportunity here in parseModels to rewrite the response in the appropriate format.

Bypass Ajax request within javascript promise in Unit Testing

I have a function called getStudentData(),returns resolved data.
Inside getStudentData(), I have an Ajax request.
I want to Bypass Ajax request in my unit test case using Mocha , so that when i make a call to getStudentData(), the data should be returned.
Please find the code below:
getStudentData: function() {
return studentData || (studentData = new Promise(function(resolve, reject) {
var request = {
//request data goes here
};
var url = "/student";
$.ajax({
url: url,
type: "POST",
data: JSON.stringify(request),
dataType: "json",
contentType: "application/json",
success: function(response, status, transport) {
//success data goes here
},
error: function(status, textStatus, errorThrown) {
reject(status);
}
});
}).then(function(data) {
return data;
})['catch'](function(error) {
throw error;
}));
}
Please let me know how to Bypass Ajax request By stubbing data using sinon.js .so that when i make a call to getStudentData() , data should be returned.
First of all doing:
then(function(data){ return data; })
Is a no-op. So is:
catch(function(err){ throw err; });
Now, your code uses the explicit construction anti-pattern which is also a shame, it can be minimized to:
getStudentData: function() {
var request = {
//request data goes here
};
var url = "/student";
return studentData ||
(studentData = Promise.resolve($.ajax({
url: url,
type: "POST",
data: JSON.stringify(request),
dataType: "json",
contentType: "application/json" })));
}
Now, that we're over that, let's talk about how you'd stub it. I'd do:
myObject.getStudentData = function() {
return Promise.resolve({}); // resolve with whatever data you want to test
};
Which would let you write tests that look like:
it("does something with data", function() { // note - no `done`
// note the `return` for promises:
return myObj.getStudentData().then(function(data){
// data available here, no ajax request made
});
});
Although in practice you'll test other objects that call that method and not the method itself.

Is it possible to make multiple calls using Jsonp with deferred objects?

I'm trying to make two or more requests all at once if that's even possible? I'm concerned about speed since after the first request is made I want to display that info onto a web page and then do the same for each additional url.
I've been reading about deferred objects and trying some examples, and so far I've tried to do this,
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script >
$(document).ready(function($) {
// - 1st link in chain - var url = 'https://www.sciencebase.gov/
catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=60&offset=0&format=jsonp';
// - 2nd link in chain - var url = 'https://www.sciencebase.gov/
catalog/itemLink/504216b6e4b04b508bfd333b?format=jsonp&max=10';
// - 3rd (and last) link in chain - var url = 'https://www.sciencebase.gov/
catalog/item/4f4e4b19e4b07f02db6a7f04?format=jsonp';
// parentId url
function parentId() {
//var url = 'https://www.sciencebase.gov/catalog/items?parentId=
504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp';
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/items?parentId=
504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {},
error: function(e) {
console.log(e.message);
}
});
}
// itemLink url
function itemLink() {
//var url = 'https://www.sciencebase.gov/catalog/itemLink
/504216b6e4b04b508bfd333b?format=jsonp&max=10';
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/itemLink
/504216b6e4b04b508bfd333b?format=jsonp&max=10',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {},
error: function(e) {
console.log(e.message);
}
});
}
// Multiple Ajax Requests
$.when( parentId(), itemLink()).done(function(parentId_data, itemLink_data) {
console.log("parentId_data.items[0].title");
});
});
But it doesn't seem like the functions are functioning. I was expecting to be able to put some stuff after the .when() method inside the function to tell my program what to do, but I'm not getting anything displayed??
Thanks for the help!
Part of the problem is that in the done handler for $.when, the arguments that are passed to the callback are the array of arguments for each request, not simply the data that you want to use. You can get around this by using .pipe as in the example below.
Also, don't specify jsonpCallback unless you have a very good reason, most of the time you want to let jQuery manage that internally for you.
Here's a working example tested on JSFiddle
jQuery(function($) {
function parentId() {
return $.ajax({
url: 'https://www.sciencebase.gov/catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp',
dataType: 'jsonp',
error: function(e) {
console.log(e.message);
}
// We'll use pipe here so that rather than the value being passed to our $.when handler
// is simply our data rather than an array in the form of [ data, statusText, jqXHR ]
}).pipe(function( data, statusText, jqXHR ) {
return data;
});
}
function itemLink() {
return $.ajax({
url: 'https://www.sciencebase.gov/catalog/itemLink/504216b6e4b04b508bfd333b?format=jsonp&max=10',
dataType: 'jsonp',
error: function(e) {
console.log(e.message);
}
}).pipe(function(data) {
return data;
});
}
// Multiple Ajax Requests
$.when( parentId(), itemLink()).done(function(parentId_data, itemLink_data) {
console.log( parentId_data, itemLink_data );
});
});

Resources