I am visiting a site that emits a (large) JSON response. A click triggers the request:
casper.then(function li10() {
casper.click(SEARCH_BUTTON_CSS);
});
But according to my web proxy, the client closes the connection before receiving the entire response. I've tried waiting for the URL to appear. It waits for the URL as expected, but that doesn't appear to be sufficient:
casper.then(function li11() {
casper.waitForUrl(/\/search-results\/p\?/,
function() {
var search_url = casper.getCurrentUrl();
console.log('found search results, url = ' + search_url);
},
function() {
console.log('failed to find search results');
casper.exit();
},
10000);
});
So: what is something dependable that I can wait for that will guarantee that the JSON code has completely loaded before proceeding to the next step?
I'm assuming that you would fill a search field, click a button and the JavaScript makes an Ajax request to receive a JSON response to then parse it and display the results.
casper.waitForUrl() is used to wait for the page URL to change to the specified one. It has nothing to do with resources that are loaded separately such as AJAX responses.
You either need to
find out the specific URL that is requested for the search action and use casper.waitForResource() to wait for that specific resource or
devise a specific selector that appears when the search data is parsed and injected into the page with casper.waitForSelector().
Related
I've been trying to figure out how to reload a page and pull dynamic info from a server without users noticing the page has been reloaded. For instance, if I want to create a 'live' message board system when the board updates every time other people make a comment or post a message.
I noticed that Javascript has a boolean function .reload() that when set to false reloads the page from the cache and when set to true reloads the page from the server, but from what it looks like, the function does something similar to reloading the browser. Is there another way do what I'm trying to do?
Something like this...
function getContent()
{
return new Promise(function(resolve, reject){
var url = "http://yourendpoint.ext"
$.ajax({
url: url,
success: function(data)
{
resolve(data);
},
error: function(err)
{
reject(err);
}
});
}));
}
// Usage
getContent()
.then(function(data)
{
$('#some-element').html(data);
});
Are you sure you really want to do an reload?
What you could do is make an AJAX Request to the server and display the result, without even reloading the Page. I would recommend using jQuery for this, just out of comfort.
AJAX stands for Asynchronous JavaScript and XML. In a simple way the process could be:
User displays page, a timer is started
Every 10s (or 20s or whatever) you do an AJAX Request using JavaScript, asking the server for new data. You can set a callback function that handles the result data.
Server answers with result data, your callback function inserts the new data.
Code Example (taken from jQuery Docs):
$.ajax({
method: "POST",
url: "target.php",
// Data to be sent to the server
data: { name: "John", location: "Boston" },
// success will be called if the request was successfull
success: function( result ) {
// Loop through each Element
$.each(result.newElements, function(index, value) {
// Insert the Element to your page
$('.classOfYourList').append(value);
}
});
});
Just set the proper endpoint of your server as the target and insert whatever you want to do in the success function. The function will get an answer containing whatever you sent to it from the server. More Information in the jQuery Documentation:
You can Achive what you want using AJAX. you can use ajax with either javascript or jquery. You can load the content you want dynamically without reloading the entire page. here is a quick example.
Here is a <div> with id load where your content will be loaded.
<div id="load">Loaded Content:</div>
<button id="load_more">load more</button>
JQuery to request for the data, where getdata.php is the php file which will send data you want to display.
<script type="text/javascript">
$(document).ready(function(){
$("#load_more").click(function (){
$.post("getdata.php", {variable1:yourvariable, variable2:ifneeded},function(data){
//data is the string or obj or array echoed from getdata.php file
$('#load').append(data); //putting the data into the loaded div.
}
});
});
});
</script>`
finally getdata.php file
<?php
//fetch data from Databas eif needed. or echo ut what you want to display in the div.
echo "This is a small example of using JQuery AJAX post request with PHP.";
?>
Hope that helps!
After the user submits a form a new view for the results will be displayed. The results view will use the form fields to create a JSON object, send the JSON with an ajax request to the server and receive a JSON response that has all of the results. The results are then rendered with the view. This all works fine but when the results page is refreshed all of the results are gone. How would I make it so that my results will continue to show up after I refresh the page? What I'm trying to do now is alter the URL so that it will contain the query and then the results view will use the URL to form a request and send it to the server. Is this the recommended course of action for what I'm trying to achieve here? Thanks.
You will need to call the function which calls the ajax request on page load.. your values are getting lost as it will reset to default undefined/null etc when the user loads the page again.
If you want the onload method to take parameters, you can do something similar to this:
window.onload = function() {
// put something here so the function will not call if the ajax call has not been called beforee
yourFunction(param1, param2);
};
This onload will call the function for you therefore no matter what running the ajax call each time.
of course you will need validation so it does not call that function if the ajax request has not been used before.i.e. something in the query string when its successful etc.
My scenario:
I have a page—let's call it items.aspx—that has an HTML table that is generated with a $.get() call to my ASP Web API controller. When a user clicks on one of the items in the HTML table, the user is sent to a page representing that item's details—let's call that one itemDetails.aspx. I predict it will be common to view the itemDetails.aspx page and then decide to cancel and redirect back to the items.aspx page.
The problem:
The problem is that each time the items.aspx page is loaded, the ajax call runs again and it takes a couple seconds to populate the table.
The question:
Is it possible to, when the user clicks the item to go to the itemDetails.aspx page, store/cache the HTML output of the table for a limited time? Since I only want this to happen if the user clicks the item link, I figured javascript would be the best tool.
You could use a function that returns a jQuery Promise for the HTML, whether it is loaded from a local cache or an AJAX request.
A simple example:
// Refers to cached HTML when available
var cached;
// Returns a promise for the HTML
function getHtml() {
var defer;
if(cached) {
defer = new Deferred();
defer.resolve(cached);
} else {
defer = $.get(/* ... */);
defer.then(function(response) {
cached = response;
})
}
return defer.promise();
}
Usage:
getHtml().then(function(html) {
$container.html(html);
})
A real implementation would probably do something to prevent concurrent $.get calls, and expire the cache when required.
This is similar to, but not the same as How can I refresh a page with jQuery?:
I bring up a modal form that collects some stuff from the user and passes it off to the server via a $.ajax() call. The server sends back a path that should become the new window.location of the browser. So the ajax call wants to be something like:
$.ajax({
// stuff
success: function (destination) {
// other stuff
window.location = destination;
}),
// still more stuff
});
This works fine as long as destination is a pure path, like /some_path and if the browser is not currently on that page. However, if the path is the page that I'm currently on and also includes a target -- /some_path#some_target, I lose: the browser simply repositions the page at the specified target, but does not hit the server for a fresh view of the page, which I need (since the server has done some stuff during the ajax call).
So, maybe I just add a location.reload() after the window.location call? That would work when the code is running on the page to which it's being returned, I think. But if I'm on another page, I get hit by a race condition, where the reload is called before the browser has finished making the window.location change, and I get the old page reloaded, not the new destination.
Blurgh. Is there any way around this?
One approach would be to check if window.location.pathname (which is the path without # or ?) is the same as destination within your success callback:
success: function (destination) {
// other stuff
if (destination === window.location.pathname) {
window.location.reload(); // reload if we are on the same page
} else {
window.location = destination; // otherwise, navigate to "other" page
}
}),
window.location.reload() reloads the current page with POST data, while window.location.href=window.location.href does not include the POST data.
I have a ajax post request, which dynamically loads some math content like below
// post comment
$post_comment.on("click", "[data-submit='post-comment']", function() {
$.ajax({
success: function(response) {
if(response.success) {
$('#comment-list').load(' ' + '#comment-list');
MathJax.Hub.Queue(["Typeset",MathJax.Hub, "comment-list"]);
}
},
});
});
The mathjax command above mentioned is unable to render the math script loaded dynamically.
While when I execute the same command on command-line, its working!!
It would be nice if someone explains why this is happening and how to fix
The load() method uses ajax which executes asynchronously meaning after the request is sent to the server the statements after that will continue executing without waiting for the response from server comes back.
In this case when the load request is sent, before #comment-list is populated with the response the MathJax.Hub.Queue(["Typeset",MathJax.Hub, "comment-list"]); statement will get executed, thus it is not rendering anything.
The solution is to use a callback provided by load to run the statements which has to work on elements loaded by the ajax request
Ex
$('#comment-list').load(' ' + '#comment-list', function(){
MathJax.Hub.Queue(["Typeset",MathJax.Hub, "comment-list"]);
});