Knockout: Make the whole page wait for result of ajax call - javascript

Basically, I would like to call to geoip.com to get the information of the browser user and then use their location to render correctly. But the problem is that using knockout, the page get rendered without waiting for the result of ajax (Even all render code stay behind a success callback). How can I achieve the result?
Changing from ajax to synchronous also does not work.
I am using knockout to bind data to a custom handler in view
<div id="main_layout" class=layout data-bind="svg:handle">
....Other HTML....
Inside the svg.handle of its viewModel
ko.bindingHandlers.svg = {
init: function (element, valueAccessor) {
$.ajax({
url: '//freegeoip.net/json/',
type: 'POST',
dataType: 'jsonp',
success: function(location) {
// Do everything
}
}
// return viewModel for the HTML

Related

Saving Variable in AJAX success call to pass in Another AJAX success call

Creating a 'refresh' button via jQuery, AJAX and PHP.
This particular one I'm having control two DOM instances (divs) - #sold-container, and also #totalorderswidget.
$(document).ready(function() {
$(function() {
$('#orderfeed').on('click', function() {
var orders;
$.ajax({
type: 'POST',
url: 'liveorderwidget.php',
beforeSend: function() {
$('#sold-container').html('<div class="page-loader"></div>');
$.ajax({
url: "totalorderswidget.php",
beforeSend: function() {
$('#totalorderswidget').html('<div class="page-loader"></div>');
},
success: function(orderdata) {
// $('#totalorderswidget').html(orderdata);
orders = orderdata;
}
});
},
success: function(solddata) {
$('#sold-container').html(solddata);
$('#totalorderswidget').html(orders);
}
})
});
});
});
I didn't like how each DIV was updating and showing my page-loader CSS at different times, so I thought I'd try and grab the data to pass and display them both at the same time (get data from the first ajax call, display both on the second).
This is working as two normal AJAX calls, and each appends the success html to each id on it's own. (uncommenting // $('#totalorderswidget').html(orderdata); works),
but initializing a variable like var orders; outside the functions and trying to put the data in the success call (orders = orderdata;) does not work.
Doing a console.log on the first AJAX success call (orderdata) brings back the expected response, but trying to use it in the second AJAX call ($('#totalorderswidget').html(orders);) does not work and a console.log brings back undefined for the order variable.
What must I change in order to grab data from the first success call function and bring this data into the second/final ajax success call?

I made an AJAX call and jQuery won't add classes after the call anymore

I've made an AJAX call that receives dynamic content and "lazyloads" it on the page. I want to apply a filter to the lazyloaded images received from the AJAX call, but somehow I can't add classes or the filter I want to the images
this is my current script for adding the filter:
function authenticFilter() {
$("img").addClass("authenticFilter");
$(".authenticFilter").css({"filter": "sepia(80%) grayscale(1) contrast(1) opacity(0.7)", "-webkit-filter": "sepia(80%) contrast(1) opacity(0.7)"});
}
authenticFilter();
This is the basic ajax call:
$.ajax({
type: "GET",
url: "php/database.php",
data: {
'offset': 0,
'limit': $loadAmount
},
success: function(data){
$('.articles').append(data);
increaseArticles += 10;
}
});
I've tried serveral things including putting it outside the document ready function and using it out of the function, but it doesn't seem to work. The internet doesn't offer much help either, because only the click event outside ajax calls is popular apparently.
You probably need to call authenticFilter() from within your ajax success callback:
success: function(data){
$('.articles').append(data);
authenticFilter();
increaseArticles += 10;
}

AngularJS - ui-grid - Data display issue

I am implementing http://ui-grid.info/ in my application.
I am populating the grid with ajax call like this :-
$scope.getGrid = function () {
jq.ajax({
type: "POST",
url: "getData",
dataType: "html",
traditional: true,
data: { columnDb: $scope.columnDb },
success: function (data) {
var dataObj = jQuery.parseJSON(data);
......
$scope.gridOptions.data = $scope.myData;
});
}
There is a weird problem i am facing. on the above function call, i can see nothing in my HTML, But if i just mouse scroll on the Grid area the data gets displayed, even if i open Inspect Element in Chrome, the data gets displayed.
Any Idea How to solve this?
This code does not lead to an Angular digest when the ajax call returns, and hence you don't see anything change in your on screen 'view'. So you can either:
Use $http for your ajax call
Add a $scope.$apply() to the callback function.
I would suggest using 1

Dialog popup and spinner not behaving correctly

I want to popup/display a dialog. It has two tabs and in each of these tabs there is a table (lets say table1 and table2).
Both of these tables contain data those are populated by a rest/ajax service (lets say service1 and service2).
When each of these rest services completes, the table component is populated with the data.
On top of this, the dialog has a spinner widget activated when the dialog first pops up.
The spinner widget is deactivated when BOTH of the rest services have completed.
For table1 I have code that looks a bit like this :
this.updateTable1 = function (dialog)
{
dialog.setSpinner(true)
var call = {}
call.url = 'service1';
call.xmlHttpReq = $.ajax({
url: url,
dataType: 'json',
async: true,
type: 'GET'
}).always(
function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown)
{
dialog.table1.loadData(processedDataOrXHRWrapper);
dialog.setSpinner(false)
});
};
For table2 the code is pretty much the same.
Which means that it also has dialog.setLoading(false). This means that whichever process finishes first, the spinner is deactivated, which is incorrect behaviour.
Somehow the two ajax calls need to know about each other, but I don't like that idea :(. Should I have some kind of third object that stores state of which processes have finished?
I tried using ajax calls in sync mode, but that just blocks the display thread in the browser.
You can use Deferred promises to implement this.
var updateTable1 = function (dialog)
{
return $.ajax({
url: url,
dataType: 'json',
async: true,
type: 'GET'
}).always(
function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown)
{
dialog.table1.loadData(processedDataOrXHRWrapper);)
});
};
// and same for updateTable2
dialog.setSpinner(true);
$.when(updateTable1(dialog), updateTable2(dialog)).always(function() {
dialog.setSpinner(false);
});
Only issue with the above is that, if the ajax call in updateTable1 or updateTable2 fails, the always function is immediately called. If you don't want this - see the $.whenall function in the answer to this question:
jquery deferred - "always" called at the first reject

How can one trigger a function onchange of a div?

Here's a question which has proved very difficult to find an answer online for.
Let's say a user runs an ajax function onclick to fill the contents of a div.
But, what if the ajax output is php, and for that onclick, i want other divs on the page to change in a manner that is dependent on the contents of div1?
This means I need to wait for div1 to actually change so i can use the ajax output of the php calculations to adjust div2 accordingly.
After some testing i've found out that i cant add a call to a second ajax function at the end of the first because it seems to run before the div content from the first ajax call actually changes.
So how can i trigger an ajax call onchange of the contents of a div?
All ajax calls take a callback to run when the call completes, put your logic in there.
You could use Jquery
$('#div1').change(function(){
doAjax( $(this).html() );
});
Or in the callback of the ajax
$.ajax({
url: 'http://yoururl.com',
type: 'post',
data: { key: value },
success: function( data ){
doAjax( data );
}
});
If you are aware of jquery, this is what you should try:
$.ajax({
traditional: true,
type: "post",
url: '<your_url>',
beforeSend: function () {
//your logic to perform operation before ajax request
},
data: {
//data to send
},
success: function(response) {
//your logic to perform operation after ajax request
//here make another ajax request
}
});

Categories

Resources