why browser request for image after ajax? - ajax

I'm using backbone and nodejs for a single page webapp.
I got a view, which has a model(a blog post) in it. when user click on 'like' button, the view will start ajax send the user'id to server to let the like number +1.
it looks like this:
this.model.save({
likedBy: userModel.get('_id')
}, {
url: '/posts/' + this.model.get('_id') + '/like',
success: function() {
// do something
},
patch: true
});
my problem is, when this code got run. browser start http request to retrieve all the images on the screen, and re-render them. so the screen got a "shake" after user clicked the like button.
this is not happening everywhere, but what caused this? how to stop the "shake"?
thanks for any advance.

When you call this.model.save() the model will update his data in the server and will call your view's render function. The render method will create a new DOM element and replace the old DOM element, that's what causing the flickering (it requests the images again).
I assume you have an API call for Like action (if not it's better to have one) so you can make a sperate AJAX call for like action on your model by adding a function like so:
addLike : function(data) {
Backbone.ajax({
url: '/api/like/'+ this.get('id'),
method: 'POST',
data: data,
success: options.success,
error: options.error
});
}

Related

$.ajax().success not working only in firefox

I have an ajax function like so:
function RunSubmit() {
$.ajax({
url: '#Url.Action("Contact", "Public")',
type: "POST",
data: $('#contactForm').serialize(),
dataType: 'jsonp',
crossDomain: true,
success: function (result) {
alert("hit success function");
if (result.validForm) {
alert("At redirect. Url is: " + result.url);
window.location.assign(result.url);
//console.log("valid form");
} else {
$('#registerForForm').html(result);
//console.log("BAD FORM");
alert("ELSE CALLED");
}
},
error : function(ob1, ob2, ob3)
{
},
complete: function(val)
{
//This is being hit but it appears no value is being returned from the controller (FireFox)
}
});
Strange thing is it works in IE and Chrome but not FF. I have tried running the post with dataType: 'json' without the dataType and without the crossDomain property. Looking at the console on FF I can see that we are having numerous cross domain request errors mainly coming from google fonts. (This does not happen on chrome or ie). In our controller we are making a hardcoded http request to another server on a different host so I can see where the issue might be arising. The way we have dealt with this issue before is by adding a crossdomain.xml file to the root of our project. Something like this
<?xml version="1.0" encoding="utf-8" ?>
<cross-domain-policy>
<allow-access-from domain="*.xyz.com"/>
<allow-access-from domain="*.abc.com"/>
<allow-access-from domain="*.123.net"/>
<allow-access-from domain="http://university.abc.com"/> //this is the site we are sending a request to in our controller
</cross-domain-policy>
So I have searched and come across multiple posts on SO where the success function was not being called on an ajax post. Check my error objects the only information I am getting back is "error". This javascript should be receiving a url back and redirecting; however, what it is doing is rendering the JSON return value to the screen.
This is the line of code that returns our Json from our controller.
return Json(new { validForm = true, url = "/Public/ContactComplete" }, JsonRequestBehavior.AllowGet);
The line looks fine to me and the Json being returned is perfect json so it should not be a parsing error on the jquery side.
This was an interesting situation. I'm adding this to my list of reasons as to why a form may not post back in MVC. The outside firm we hired to develop our product created a 'hack' to get around an issue where Chrome would not post back if you wished to disable the submit button (to prevent double post) on the click of the button itself. To get around this the developer wrote an ajax script submitting the form manually on click. This in turn blew up functionality in firefox. There was some weird double posting going on and for whatever reason FF would render JSON to the screen instead of catching the Json back and running the success function.
Long story short:
If you are disabling a submit button to prevent double post then disable it on the form submit event.
pseudo code
$('#submit-button').on('click', function() { this.attr('disabled', true);}
Is not the way to go. The below is what fixed it for me
$('form').on('submit', function() { $('#submit-button').attr('disabled', true);}

How do they do this, ajax, json

I have been tasked with adding some functionality to a site similar to this screen on flickr.
Does anyone have any idea how they do the photostream on the right. The images are not in the javascript, json or there is no ajax request.
It would be really useful if anyone had an idea how they did this.
There is an AJAX request performed as you scroll.
Open the console in your browser and look at the network tab. It will show a link similar to this:
http://www.flickr.com/services/rest/?format=json&clientType=yui-3-flickrapi-module&api_key=8800e2eb03db7fb99992039f14061dcf&auth_hash=e65c85db55a2671d8d5968171150c516&auth_token=&secret=9978895fa92da630&photo_id=3396195710&num_prev=4&num_next=0&order_by=&extras=url_sq%2Curl_q%2Curl_t%2Curl_s%2Curl_m%2Curl_z%2Curl_c%2Curl_l%2Curl_o%2Cvideo_size%2Cowner_name%2Cpath_alias%2Cicon_server%2Cneeds_interstitial%2Ccount_comments%2Ccount_faves%2Curl_h%2Curl_k&method=flickr.photos.getContext&jsoncallback=YUI.flickrAPITransactions.flapicb23&cachebust=1358811052893
This is the restful link which returns JSON data. This JSON data contains the urls for the thumbnails of each of the photos, plus other information.
1st There is ajax request when you scroll thumbnails on the right.
And I think that they make an ajax request with the last photo ID in the stream, the next pic in database or prev and the user who uploaded pics and surely others params...
You want a script file that will give you picture thumb encoded in base64, url of the picture and next pictures id in database..
Example
$("#photostream > .scroll").click(function(){
leftOrRight = $(this).attr("id"); // Assume that there is two buttons to get next or previous img with id #next and #prev
$.ajax({
type: "GET",
url: urlOfTheScriptFileThatWillProvideYouData.php, //aspx, jsp ...
dataType: "json",
data: "userId, photoId, leftOrRight",
success: function(yourJson) {
//... Do something with your data and append it in the slider etc..;
},
error: function (xhr, textStatus, errorThrown) {
$("#error").html(xhr.responseText);
}
})
})
Look at URL
http://www.flickr.com/photos/roblawton/3847619643/in/photostream/
http://www.flickr.com/photos/USER-ID/PHOTO-ID/in/photostream/

How to properly clear the content of an Ember.Enumerable?

I was looking at Emberjs recently and found this useful article written by one of its main contributors: Advice on & Instruction in the Use Of Ember.js
It walked me through an example which fetch a list of user data from a server and render them on screen. I'll briefly explain how it worked:
The app contacts the server to fetch a list of user data though ajax
call.
At the end of the ajax call an empty enumerable is returned
immediately, which is later used as a property of a controller.
Once the ajax call is completed, it populates the enum with data which
in turns update the controller's property, and finally triggers an
automatic re-rendering.
This works fine as long as the list is not revisited. As a user revisit the list, say he/she navigates to another state and then comes back, the logic will be triggered again, fetching the data from server and populates the list. However, the list this time is not empty! Thus we have a list of duplicated data. I would like to resolve this by clearing the content of the list when the ajax call is successful. Below is the code for the ajax call:
allAwesomebergs: [],
fetch: function(){
$.ajax({
url: 'https://api.github.com/repos/emberjs/ember.js/contributors',
dataType: 'jsonp',
context: this,
success: function(response) {
response.data.forEach(function(awesomeberg){
this.allAwesomebergs.addObject(App.Awesomeberg.create(awesomeberg))
}, this);
}
});
return this.allAwesomebergs;
},
The above code does not clear the content of the list. I tried adding a line "allAwesomebergs = []" at the beginning of the success function, but what I got was just a blank screen. I thought I may not be doing this correctly, but I looked at the document from Ember and didn't see anything about clearing the content of an Enumerable.
Thus the question is: what is the easiest way to resolve this duplicate loading issue? Clearing the content before hand seems the most obvious but I can't make it work.
You can call clear() before you start adding the new objects. See this documentation.
New code would be:
allAwesomebergs: [],
fetch: function(){
$.ajax({
url: 'https://api.github.com/repos/emberjs/ember.js/contributors',
dataType: 'jsonp',
context: this,
success: function(response) {
this.allAwesomebergs.clear();
response.data.forEach(function(awesomeberg){
this.allAwesomebergs.addObject(App.Awesomeberg.create(awesomeberg))
}, this);
}
});
return this.allAwesomebergs;
},
I think your approach was ok, but it should have been:
this.allAwesomebergs = []
It is all about the this in front of it. So clear is not needed here.

JQM (jQueryMobile) problem with AJAX content listview('refresh') not working

This is a mock of what I'm doing:
function loadPage(pn) {
$('#'+pn).live('pagecreate',function(event, ui){
$('#'+pn+'-submit').click( function() {
$.mobile.changePage({
url: 'page.php?parm=value',
type: 'post',
data: $('form#'+pn+'_form')
},'slide',false,false);
loadAjaxPages(pn);
});
});
function loadAjaxPages(page) {
// this returns the page I want, all is working
$.ajax({
url: 'page.php?parm=value',
type: 'POST',
error : function (){ document.title='error'; },
success: function (data) {
$('#display_'+page+'_page').html(data); // removed .page(), causing page to transition, but if I use .page() I can see the desired listview
}
});
}
in the ajax call return if I add the .page() (which worked in the past but I had it out side of the page function, changing the logic on how I load pages to save on loading times), make the page transition to the next page but I can see the listview is styled the way I want:
$('#display_'+page+'_page').html(data).page();
Removing .page() fixes the transition error but now the page does not style. I have tried listview('refresh') and even listview('refresh',true) but no luck.
Any thoughts on how I can get the listview to refresh?
Solution:
$.ajax({
url: 'page.php?parm=value',
type: 'POST',
error : function (){ document.title='error'; },
success: function (data) {
$('#display_'+page+'_page').html(data);
$("div#name ul").listview(); // add div wrapper w/ name attr to use the refresh
}
});
Be sure to call .listview on the ul element
If it didn't style earlier, you just call .listview(), bot the refresh function. If your firebug setup is correct, you should have seen an error message telling you that.
I didn't have time to get down to creating some code before you posted your fix, but here's a little recommendation from me:
if(data !== null){ $('#display_'+page+'_page').html(data).find("ul").listview() }
This is a bit nicer than a new global selector. Also - you don't need the div and you can provide a detailed selector if you have multiple ULs.
caution: the above code requires data !== null. If it's null - it will throw an error.
If you add items to a listview, you'll need to call the refresh() method on it to update the styles and create any nested lists that are added. For example:
$('#mylist').listview('refresh');
Note that the refresh() method only affects new nodes appended to a list. This is done for performance reasons. Any list items already enhanced will be ignored by the refresh process. This means that if you change the contents or attributes on an already enhanced list item, these won't be reflected. If you want a list item to be updated, replace it with fresh markup before calling refresh.
more info here.

Can I make an Ajax request inside an ongoing Ajax request (e.g. on the success callback function)?

I have a jQuery application, a shopping cart, that posts back info to the server, if the text inputfield is changed. This is done in an Ajax request. Now, if the Ajaxrequest is a success, I want to reload the shoppingcart asynchronously. The code is as follows:
$(document).ready(function() {
var jInput = $(":input");
jInput.change(function() {
var vareAntal = $(this).val();
var vareID = $(this).siblings("input#vareID").val();
$.ajax({
type: 'POST',
url: 'checkout.aspx',
data: { 'ID': vareID, 'Antal': vareAntal },
success: function() {
$("#newbasket").load(location.href + " #newbasket>*", "");
}
});
});
});
This works, but only once! If I change the text inputfield, after the page is loaded for the first time, the div with the ID of newbasket reloads asynchronously. But if I try to change it again, nothing happens.
I've tried to do some debugging with Firebug, and the first time I change the text inputfield, it fires a POST-event, and afterwards a GET-event, when the POST-event is succesful. But after that, nothing happens when I change the text inputfield again.
So, how do I achieve triggering the .load() method after each text input change?
I've also tried experimenting with the .ajaxComplete() function, but that, of course, resulted in an infinite loop, since the .load() is an ajax-object.
Instead of .change(func), use .live('change', func) here, like this:
jInput.live('change', function() {
This will make the selector work on any new inputs added as well. When you're replacing the elements like you are currently, their event handlers are lost (or rather, not re-created, because you have new elements). .live() is just for this purpose, it listens for events from old and new elements, regardless of when they were added.

Resources