Monitor AJAX JSON Object download/transfer progress - ajax

I would like to know if it is possible to create a progress bar for an AJAX call where data returned is a JSON Object which represents a large database . This functions is used to synchronize between a client - server side database, and would like to show progress for users, like a normal file download...
I have tried the following without sucesss..
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", updateProgress, false);
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total * 100;
console.log(percentComplete);
} else {
console.log('Unable to compute Size');
}
}
return xhr;
},
type: "POST",
url: "http:s......"
ect....//

Probably using - XMLHttpRequest
I'm trying to achieve the same so digging it here.
Does this post work for you?

Related

Backbone set model inside ajax request

Hi all I have an app in Backbone where inside a function I want to convert price from GBP to EUR for example using a php file called with ajax.
In the success function I want to assign the converter data to my object.
But seems that not setting this because into the template uin underscore there is always the old value.
This is my function inside my model:
toJSON: function() {
var json = _.clone(this.attributes);
json.rooms = this.rooms.toJSON();
_.each(json.rooms, function(room){
var converter ="<?php echo(site_url('/backend/hotel/ajax_currency')); ?>";
$.ajax({
url: converter,
type: "POST",
data: {
from_currency : room.currency,
amount : room.price_adult
},
dataType: "json",
success: function(data) {
console.log(data);
room.price_adult = data;
}
});
});
return json;
},
I have also tried:
room.model.set('price_adult',data);
but return me error that don't find model.
How can I solve?
This is not a thing you want to put in toJSON function, I can think of several reason why it should work for you. The most important one is that toJSON function is synchronous and the AJAX response is async. so your render function is happening before you get the response from your ajax.
I would suggest having a Room model that will be responsible for the concurrency, and it's view will render it when ajax has returned and the price_adult is ready.
var Room = Backbone.Model.extend({
initialize:function(){
this.convertConcurrency();
},
convertConcurrency:function(){
var model = this;
$.ajax(.....,
success:function(data){
model.set("price_adult", data);
}
);
},
});
var RoomView = Backbone.View.extend({
initialize: function(){
this.listenTo(this.model, "change:price_adult", this.render);
if (this.model.has("price_adult")) this.render();
},
.....
});
var Rooms = Backbone.Collection.extend({...})
var RoomsView = // Rooms collection view
This way the view will be rendered only when there is a price_adult ready.
Maybe you should create a model on the client that gather the concurrency information from the server and compute the concurrency conversation by itself, so you will only have one ajax and the model will compute it for you instead of the server.

RecorderJS uploading recorded blob via AJAX

I'm using Matt Diamond's recorder.js to navigate the HTML5 audio API, and feel this question probably has an apparent answer, but i'm unable to find any specific documentation.
Question: After recording a wav file, how can I send that wav to the server via ajax? Any suggestions???
If you have the blob you'll need to turn it into a url and run the url through an ajax call.
// might be nice to set up a boolean somewhere if you have a handler object
object = new Object();
object.sendToServer = true;
// You can create a callback and set it in the config object.
var config = {
callback : myCallback
}
// in the callback, send the blob to the server if you set the property to true
function myCallback(blob){
if( object.sendToServer ){
// create an object url
// Matt actually uses this line when he creates Recorder.forceDownload()
var url = (window.URL || window.webkitURL).createObjectURL(blob);
// create a new request and send it via the objectUrl
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "blob";
request.onload = function(){
// send the blob somewhere else or handle it here
// use request.response
}
request.send();
}
}
// very important! run the following exportWAV method to trigger the callback
rec.exportWAV();
Let me know if this works.. haven't tested it but it should work. Cheers!
#jeff Skee's answer really helped but I couldn't grasps it at first, so i made something simpler with this little javascript function.
Function parameters
#blob : Blob file to send to server
#url : server side code url e.g. upload.php
#name : File index to reference at the server side file array
jQuery ajax function
function sendToServer(blob,url,name='audio'){
var formData = new FormData();
formData.append(name,blob);
$.ajax({
url:url,
type:'post',
data: formData,
contentType:false,
processData:false,
cache:false,
success: function(data){
console.log(data);
}
}); }
Server side code (upload.php)
$input = $_FILES['audio']['tmp_name'];
$output = time().'.wav';
if(move_uploaded_file($input, $output))
exit('Audio file Uploaded');
/*Display the file array if upload failed*/
exit(print_r($_FILES));
I also spent many hours trying to achieve what you are trying to do here. I was able to successfully upload the audio blob data only after implementing a FileReader and calling readAsDataURL() to convert the blob to a data: URL representing the file's data (check out MDN FileReader). Also you must POST, not GET the FormData. Here's a scoped snippet of my working code. Enjoy!
function uploadAudioFromBlob(assetID, blob)
{
var reader = new FileReader();
// this is triggered once the blob is read and readAsDataURL returns
reader.onload = function (event)
{
var formData = new FormData();
formData.append('assetID', assetID);
formData.append('audio', event.target.result);
$.ajax({
type: 'POST'
, url: 'MyMvcController/MyUploadAudioMethod'
, data: formData
, processData: false
, contentType: false
, dataType: 'json'
, cache: false
, success: function (json)
{
if (json.Success)
{
// do successful audio upload stuff
}
else
{
// handle audio upload failure reported
// back from server (I have a json.Error.Msg)
}
}
, error: function (jqXHR, textStatus, errorThrown)
{
alert('Error! '+ textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
// handle audio upload failure
}
});
}
reader.readAsDataURL(blob);
}
Both solutions above use jQuery and $.ajax()
Here's a native XMLHttpRequest solution. Just run this code wherever you have access to the blob element:
var xhr=new XMLHttpRequest();
xhr.onload=function(e) {
if(this.readyState === 4) {
console.log("Server returned: ",e.target.responseText);
}
};
var fd=new FormData();
fd.append("audio_data",blob, "filename");
xhr.open("POST","upload.php",true);
xhr.send(fd);
Server-side, upload.php is as simple as:
$input = $_FILES['audio_data']['tmp_name']; //temporary name that PHP gave to the uploaded file
$output = $_FILES['audio_data']['name'].".wav"; //letting the client control the filename is a rather bad idea
//move the file from temp name to local folder using $output name
move_uploaded_file($input, $output)
source | live demo

Multiple AJAX calls on page load

I'm attempting to pull two separate things from outside sources to put onto an HTML page I'm creating. I have a successful AJAX function to pull the most recent video from a particular Youtube channel by parsing through the XML/RSS feed for that channel. I receive this feed through an AJAX call.
I'd also like to get the most recent blog post from a Blogger account. The code for parsing the feed to get the most recent entry shouldn't be difficult, but I'm having trouble with simultaneous AJAX calls. I read somewhere that it can only handle one at a time? I'm weary about queuing them because I don't want to the content on the page to load in steps. I'd rather it all just get fetched simultaneously. How might I go about doing this?
Here is my current script:
<script type="text/javascript" charset="utf-8">
$(function() {
$.ajax({
type: "GET",
url: "http://gdata.youtube.com/feeds/base/users/devinsupertramp/uploads?orderby=updated&alt=rss&client=ytapi-youtube-rss-redirect&v=2",
dataType: "xml",
success: parseXml
});
});
function parseXml(xml) {
$(xml).find("item:first").each(
function() {
var tmp = $(this).find("link:first").text();
tmp = tmp.replace("http://www.youtube.com/watch?v=", "");
tmp = tmp.replace("&feature=youtube_gdata", "");
var tmp2 = "http://www.youtube.com/embed/" + tmp + "?autoplay=1&controls=0&rel=0&showinfo=0&autohide=1";
var iframe = $("#ytplayer");
$(iframe).attr('src', tmp2);
}
);
}
</script>
I read somewhere that it can only handle one at a time?
Either you misunderstood what the person was trying to say or they were incorrect. Javascript doesn't run any functions concurrently so someone with poor English might reword that as "can only handle one at a time" but that doesn't mean you can't make multiple AJAX calls. jQuery is smart and will do what it needs to do to make sure both calls are executed eventually.
If you'd like all the content to be loaded simultaneously the sad fact is you can't. However you can make it appear that way to the user by declaring a flag that is set by the success method of each call. Then just keep the content hidden until both flags have been set.
EDIT:
Here's a very simplistic approach to make it appear that they are fetched simultaneously:
<script type="text/javascript" charset="utf-8">
var youtubComplete = false;
var otherComplete = false;
$(function() {
$.ajax({
type: "GET",
url: "http://gdata.youtube.com/feeds/base/users/devinsupertramp/uploads?orderby=updated&alt=rss&client=ytapi-youtube-rss-redirect&v=2",
dataType: "xml",
success: parseXml
});
$.ajax({
type: "GET",
url: "http://someotherdata.com/",
dataType: "xml",
success: function() { otherComplete = true; checkFinished(); }
});
});
function parseXml(xml) {
$(xml).find("item:first").each(
function() {
var tmp = $(this).find("link:first").text();
tmp = tmp.replace("http://www.youtube.com/watch?v=", "");
tmp = tmp.replace("&feature=youtube_gdata", "");
var tmp2 = "http://www.youtube.com/embed/" + tmp + "?autoplay=1&controls=0&rel=0&showinfo=0&autohide=1";
var iframe = $("#ytplayer");
$(iframe).attr('src', tmp2);
}
);
youtubeComplete = true;
checkFinished();
}
function checkFinished()
{
if(!youtubeComplete || !otherComplete) return;
// ... Unhide your content.
}
</script>
The browser will support multiple outbound calls but there is a cap per domain. Take a look at this related Q/A How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?.
There are several good libraries for doing request scheduling including chaining and parallelizing AJAX calls. One good library is https://github.com/kriskowal/q, which provides async promises framework to enable arbitrarily complicated chaining of AJAX requests. Q minified is about 3.3KB.
// The jQuery.ajax function returns a 'then' able
Q.when($.ajax(url, {dataType: "xml"}))
.then(function (data) {
var parsedXML = parseXML(data)
...
// some other ajax call
var urls = [Q.when($.ajax(url2, {data: {user: data.userId}})),
Q.when($.ajax(url3, {data: {user: data.userId}}))];
// run in parallel
return Q.all(urls)
})
.then(function (data) {
// data retrieved from url2, url2
})

Can't get $.ajax or $.get to work

I have this $.ajax (using jquery) code, it originally was the $.get that is now commented but for some reason I'm always getting the error and I can't find anything wrong with it =/, am I overlooking something?
$.fn.randomContent = function(options){
var contentArray = new Array();
var dType = "html";
var defaults = {
xmlPath: "../xml/client-quotes.xml",
nodeName: "quote"
};
var options = $.extend(defaults, options);
alert(options);
$.ajax({
type: "GET",
url: "../xml/client-quotes.xml",
dataType: "html",
success: function(){
$(defaults.nodeName).each(function(i){
contentArray.push($(this).text());
});
$(this).each(function(){
$(this).append(getRandom());
});
},
error: function(){
alert("Something Went wrong");
}
});
/*$.get(defaults.xmlPath, function(){
alert("get");
$(defaults.nodeName).each(function(i){
contentArray.push($(this).text());
});
$(this).each(function(){
$(this).append(getRandom());
});
}, type);//$.get*/
};
Here's the getRandom() function:
function getRandom() {
var num = contentArray.length
var randNum = Math.floor(Math.random()*num)
var content = "";
for(x in contentArray){
if(x==randNum){
content = contentArray[x];
}
};
alert(content);
return content;
}
It could be that the browser is caching your GET requests. In this case, either:
ensure the server is controlling your cache options (using cache-control settings of private or no-cache)
change the method of your AJAX call to POST instead of GET
differentiate your GET request by adding querystring parameters that change with each request
I prefer option #1, specifically because POST operations are intended to change something on the server, and so we should use that method when our actions do in fact modify server state. GET requests on the other hand, are requests that do nothing more than read data.
I feel a GET request is more appropriate for this task, and so in my own code I would prevent the caching of the response.
Does that url have to be absolute? I've never tried doing ajax requests with a "../" in it. Do you have FireBug installed? You could examine the response header from the sever.

Set ajax request in joomla using mootools

I am having a prob for ajax request in joomla using mootools.
var url = '<?php echo JURI::base();?>index.php?option=com_test&task=getselectmode&selectedid='+$('parent_question').value;
var params ={method: 'post',update:'test'};
var myAjax = new Ajax(url, params);
myAjax.request();
My prob is that, is there any to set onComplete event of the ajax request.
i have set it as below on above code but nothing happen.
onComplete: function(response) { alert('Response: ' + response); }
Can you please provide full code of how to use ajax using mootools 1.1 ??
Thanks in advance
just add the onComplete to the params object, no need to add the event seaprately. also, you can use this.response.text. it can all look a bit more compacted - depends on your preference. if you don't plan on reusing the object, just call it direct and don't assign it to a variable either:
new Ajax(url, {
method: "get",
update: $("someelement"),
onComplete: function() {
alert(this.response.text);
}
}).request();
if you do something with the response text, you may want to remove the update: bit. if you need to evaluate the response (as javascript), use evalResponse: true instead of eval(this.response.text);. also handy - evalScripts: true|false if you want to do something from the server side along with the response.
This should work:
var ajaxObj = new Ajax ('index.php?option=com_yourcomponent&view=yourview&format=raw', {
method: "get"
});
ajaxObj.addEvent('onComplete', function (data) {
// data is the response text
// use as desired
});
// this initiates the call
ajaxObj.request();
maybe:
var a = new Ajax( url, {
method: 'post',
data: { parfoto: foto },
onComplete: function( response ){
..........
}
}).request();

Resources