In my website login page, there is a section to showing news.in document.ready of this page, I call a webmethod by ajax request to show these news but it need some seconds to execute completely. Meanwhile if user click on login button, login process keep in waiting until news load completely, but I want to run login process async, there is any solution to solve this problem?
note that I add async in my function like this:
$(document).ready(async function () ...
but news doesnt load any more.
you can make async request for news as below
jQuery.ajax({
url: 'http://example.com/',
success: function (result) {
if (result.isOk == false) alert(result.message);
},
async: true
});
Related
I used the post method to send some data through an API calling to Nodejs and waiting for the response after getting the response it will trigger another API. At this moment user wants to visit another page but the API calls will not be aborted. API call will do its task.
Is it possible to do so?
Call the API in redux using redux-thunk. Since redux is outside of all component. Changing page won't stop the API calling
You can just create a state variable and save the response of the post request in that variable, so it will be saved
When I implement the APIs in express, they continue to be executed even if the user navigates away, as illustrated by this example:
express()
.get("/api1", function(req, res) {
setTimeout(function() {
console.log("API call finished");
res.end();
}, 10000);
})
.get("/api2", function(req, res) {
res.end();
})
.listen(...);
The user first types http://server/api1 into their browser, which returns nothing after 10 seconds. But rather than wait, they navigate away to http://server/api2, which returns nothing immediately. But the /api1 call continues, as demonstrated by the console message after 10 seconds.
How does this differ from your case?
I'm working on automation testing using jest and puppeteer. I need to login first and then execute a testcase on the page displayed after successfully logged in.
I'm able to perform all action in login page but it is not identifying my locators on page displayed after login.
Is there something I'm missing?
Are you waiting for the page to load after login?
await ...login...
page.waitForSelector('#myId'); // replace with a selector of the page after login
// so what you want in this new page
For debug purpose i suggest you the screenshot function:
await ...login...
page.waitForSelector('#myId');
await page.screenshot({ path: 'example.png' }); // you now see what puppeteer sees
I have both a React APP and a Express API server on the same server/domain. Nginx is serving the React APP and proxying the express server to /api.
Nginx configuration
https://gist.github.com/dvriv/f4cff6e07fe6f0f241a9f57febd922bb
(Right now I am using the IP directly instead of a domain)
From the React APP, when the user does something I want him to download a file. I used a express route on my API server that serve the file. This works fine when the user put the URL.
This is my express route:
donwloadFile.route('/')
.get((req, res) => {
const file = '/tmp/PASOP180901.txt';
res.download(file);
});
This is my react redirect:
if (this.state.downloadFile === true) {
this.setState({ downloadFile: false });
setTimeout(() => {
window.location.href = '/api/downloadFile';
}, 100);
}
The address changes but the download don't start. If I press F5 then the download starts just fine. If I use a external URL to host my file, the download start just fine too.
Thanks
First things first. Don't use setTimeout, but rather use the callback function of setState to execute code after the state is set ensuring it has been modified. Calling the callback function will guarantee the state is changed before that code in the callback is executed.
from the official docs:
setState() enqueues changes to the component state and tells React
that this component and its children need to be re-rendered with the
updated state. This is the primary method you use to update the user
interface in response to event handlers and server responses.
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall. Instead, use
componentDidUpdate or a setState callback (setState(updater,
callback)), either of which are guaranteed to fire after the update
has been applied.
setState(stateChange[, callback])
The second parameter to setState() is an optional callback function
that will be executed once setState is completed and the component is
re-rendered. Generally we recommend using componentDidUpdate() for
such logic instead.
So, instead of:
if (this.state.downloadFile === true) {
this.setState({ downloadFile: false });
setTimeout(() => {
// execute code, or redirect, or whatever
}, 100);
}
you should do:
if (this.state.downloadFile === true) {
this.setState({ downloadFile: false }, () => {
// execute code, or redirect, or whatever
});
}
Now, for your specific problem
Set headers in your server side
You can set the Content-Disposition header to tell the browser to download the attachment:
from here:
In a regular HTTP response, the Content-Disposition response header is
a header indicating if the content is expected to be displayed inline
in the browser, that is, as a Web page or as part of a Web page, or as
an attachment, that is downloaded and saved locally.
Set it like this:
('Content-Disposition: attachment; filename="/tmp/PASOP180901.txt"');
Force download from the client
There are multiple ways to force the download from the client, but this is the only one I've tried.
For this to work, you have to have the content of text somehow in the client (your express route can return it for example) and create a filename for the file that will be downloaded.
let element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
Basically you are creating an empty link component, setting the data attribute to it with the text's content, attaching the link to the body, clicking the link and then removing the link from the body.
Open the link in a new tab
Opening the link in a new tab will trigger the download as well:
window.open('/api/downloadFile');
Redirect programatically
Have a look at this question in SO
You can do this:
this.props.history.push("/api/downloadFile")?
If cannot access this.props.history you can import { withRouter } from 'react-router-dom'; and export default withRouter(yourComponent); to access it.
I would like to block a URL to be called by giving the URL address, something like:
This doesn't work but something like this.
$.watch("http://www.test.com/alter.php",function(){
//It was called here
return false; //This in this scenario would block the URL to be called, it would cancel its request, it wouldn't even send the request, it would cancel before it access the web.
});
is it possible to block a URL so it doesn't get called or alter its request before its called in a tab via the Google Extensions?
thanks in advance.
You can use chrome.webRequest's onBeforeRequest method in blocking mode to cancel navigations.
Your manifest will need to declare permissions for "webRequest" and "webRequestBlocking".
Then add a background script that hooks onBeforeRequest and cancels the navigation for that URL only:
chrome.extension.onBeforeRequest.addListener(function() { return {cancel: true} },
{ urls: ["http://www.test.com/alter.php"] },
["blocking"]
);
I know that you can add a listener to the chrome.tabs.onUpdated event so that you can run code when a new tab is opened or the url of a tab changes.
However I was wondering is there a similar event/hook you can listen to so that you can run code when an AJAX call returns?
I'm asking because I need to check a web page every 3 seconds to see if certain text has appeared through AJAX. So basically I have to poll the page. Obviously it would be more efficient if I didn't have to poll the page and if I could run the code only when AJAX calls return as that is when I need to do the scan.
So is there a hook/even for this or will I just have to stick to polling the page?
There is the experimental webRequest API, that allows you to hook into all HTTP requests made by the browser. Since it's experimental you'd have to enable the --enable-experimental-extension-apis flag in chrome://flags or on the command line
That callback would be executed by the same javascript that called that ajax event. Its usually referred to as an ajax callback method.
In jQuery its:
$.ajax({method: "GET", url: 'some url' }).complete(function() { //do your function here });
in Mootools its:
new Request.JSON({ method: "GET", url: 'someurl', onComplete: function() { //do your function here });
In plain old javascript, you have to write in functionality for a custom callback into your XmlHttpRequest function as a function that executes when a certain ajax status code is reached