How to execute clipboard copy, window opening, event handler, and setInterval in synchronous fashion?
I am trying to do the following actions in order:
1. Create filename
2. Copy that filename to the clipboard
3. Open a window to a specific url
4. Click a specific div on the new window
5. Close the window
6. Now, I can print and simply paste the copied filename and finally print to pdf
I need these actions to happen one after the other. I need to run this logic inside of a loop (or at least execute it 200 times). So I need these steps to happen and THEN move to the next item in the html table that I am traversing.
let obj = {};
const copyToClipboard = (text) => {
const tempElem = document.createElement('input');
document.body.appendChild(tempElem);
tempElem.setAttribute('value', text);
tempElem.select();
document.execCommand("copy");
document.body.removeChild(tempElem);
};
const traverse = (i, inObj) => {
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
}, 1000);
} else{
console.log('Failure!');
}
};
for(let i = 0; i < tableSize; i++{
traverse(i, obj);
}
Some pieces of my code will execute before the others. For example, the windows will all open at once and then the remaining actions will take place. I need this code to execute completely inside of a loop before the next index iteration.
javascript asynchronous dom promise async-await
add a comment |
I am trying to do the following actions in order:
1. Create filename
2. Copy that filename to the clipboard
3. Open a window to a specific url
4. Click a specific div on the new window
5. Close the window
6. Now, I can print and simply paste the copied filename and finally print to pdf
I need these actions to happen one after the other. I need to run this logic inside of a loop (or at least execute it 200 times). So I need these steps to happen and THEN move to the next item in the html table that I am traversing.
let obj = {};
const copyToClipboard = (text) => {
const tempElem = document.createElement('input');
document.body.appendChild(tempElem);
tempElem.setAttribute('value', text);
tempElem.select();
document.execCommand("copy");
document.body.removeChild(tempElem);
};
const traverse = (i, inObj) => {
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
}, 1000);
} else{
console.log('Failure!');
}
};
for(let i = 0; i < tableSize; i++{
traverse(i, obj);
}
Some pieces of my code will execute before the others. For example, the windows will all open at once and then the remaining actions will take place. I need this code to execute completely inside of a loop before the next index iteration.
javascript asynchronous dom promise async-await
2
Wrap the async operations in Promises and chain them or use async/await with them.
– Jared Smith
Dec 29 '18 at 18:58
Everything in your question exceptsetInterval()
is synchronous because JavaScript runs synchronously. The callback fromsetInterval()
will also run synchronously. It's just the timing function of the timer that will run asynchronously.
– Scott Marcus
Dec 29 '18 at 18:59
Where's your loop?
– T.J. Crowder
Dec 29 '18 at 19:08
Thanks everyone for the replies! I have added my loop and a revision.
– God Complex
Dec 29 '18 at 19:13
add a comment |
I am trying to do the following actions in order:
1. Create filename
2. Copy that filename to the clipboard
3. Open a window to a specific url
4. Click a specific div on the new window
5. Close the window
6. Now, I can print and simply paste the copied filename and finally print to pdf
I need these actions to happen one after the other. I need to run this logic inside of a loop (or at least execute it 200 times). So I need these steps to happen and THEN move to the next item in the html table that I am traversing.
let obj = {};
const copyToClipboard = (text) => {
const tempElem = document.createElement('input');
document.body.appendChild(tempElem);
tempElem.setAttribute('value', text);
tempElem.select();
document.execCommand("copy");
document.body.removeChild(tempElem);
};
const traverse = (i, inObj) => {
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
}, 1000);
} else{
console.log('Failure!');
}
};
for(let i = 0; i < tableSize; i++{
traverse(i, obj);
}
Some pieces of my code will execute before the others. For example, the windows will all open at once and then the remaining actions will take place. I need this code to execute completely inside of a loop before the next index iteration.
javascript asynchronous dom promise async-await
I am trying to do the following actions in order:
1. Create filename
2. Copy that filename to the clipboard
3. Open a window to a specific url
4. Click a specific div on the new window
5. Close the window
6. Now, I can print and simply paste the copied filename and finally print to pdf
I need these actions to happen one after the other. I need to run this logic inside of a loop (or at least execute it 200 times). So I need these steps to happen and THEN move to the next item in the html table that I am traversing.
let obj = {};
const copyToClipboard = (text) => {
const tempElem = document.createElement('input');
document.body.appendChild(tempElem);
tempElem.setAttribute('value', text);
tempElem.select();
document.execCommand("copy");
document.body.removeChild(tempElem);
};
const traverse = (i, inObj) => {
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
}, 1000);
} else{
console.log('Failure!');
}
};
for(let i = 0; i < tableSize; i++{
traverse(i, obj);
}
Some pieces of my code will execute before the others. For example, the windows will all open at once and then the remaining actions will take place. I need this code to execute completely inside of a loop before the next index iteration.
javascript asynchronous dom promise async-await
javascript asynchronous dom promise async-await
edited Dec 29 '18 at 19:12
God Complex
asked Dec 29 '18 at 18:56
God ComplexGod Complex
295
295
2
Wrap the async operations in Promises and chain them or use async/await with them.
– Jared Smith
Dec 29 '18 at 18:58
Everything in your question exceptsetInterval()
is synchronous because JavaScript runs synchronously. The callback fromsetInterval()
will also run synchronously. It's just the timing function of the timer that will run asynchronously.
– Scott Marcus
Dec 29 '18 at 18:59
Where's your loop?
– T.J. Crowder
Dec 29 '18 at 19:08
Thanks everyone for the replies! I have added my loop and a revision.
– God Complex
Dec 29 '18 at 19:13
add a comment |
2
Wrap the async operations in Promises and chain them or use async/await with them.
– Jared Smith
Dec 29 '18 at 18:58
Everything in your question exceptsetInterval()
is synchronous because JavaScript runs synchronously. The callback fromsetInterval()
will also run synchronously. It's just the timing function of the timer that will run asynchronously.
– Scott Marcus
Dec 29 '18 at 18:59
Where's your loop?
– T.J. Crowder
Dec 29 '18 at 19:08
Thanks everyone for the replies! I have added my loop and a revision.
– God Complex
Dec 29 '18 at 19:13
2
2
Wrap the async operations in Promises and chain them or use async/await with them.
– Jared Smith
Dec 29 '18 at 18:58
Wrap the async operations in Promises and chain them or use async/await with them.
– Jared Smith
Dec 29 '18 at 18:58
Everything in your question except
setInterval()
is synchronous because JavaScript runs synchronously. The callback from setInterval()
will also run synchronously. It's just the timing function of the timer that will run asynchronously.– Scott Marcus
Dec 29 '18 at 18:59
Everything in your question except
setInterval()
is synchronous because JavaScript runs synchronously. The callback from setInterval()
will also run synchronously. It's just the timing function of the timer that will run asynchronously.– Scott Marcus
Dec 29 '18 at 18:59
Where's your loop?
– T.J. Crowder
Dec 29 '18 at 19:08
Where's your loop?
– T.J. Crowder
Dec 29 '18 at 19:08
Thanks everyone for the replies! I have added my loop and a revision.
– God Complex
Dec 29 '18 at 19:13
Thanks everyone for the replies! I have added my loop and a revision.
– God Complex
Dec 29 '18 at 19:13
add a comment |
1 Answer
1
active
oldest
votes
The only asynchronous thing I see in your code is traverse
's completion. So simply define traverse
to return a promise. Given the code in traverse
, this is probably easiest if you do it explicitly:
const traverse = (i, inObj) => {
return new Promise((resolve, reject) => { // <===========================
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
resolve(); // <===========================
}, 1000);
// *** Probably want to do a timeout here in case the window never loads
} else{
console.log('Failure!');
reject(); // <===========================
}
});
};
Then:
If you can use
async
syntax, write your loop usingawait
on the promise returned bytraverse
. Example:
// In an `async` function
try {
for (let i = 0; i < tableSize; ++i) {
await traverse(i, obj);
}
// Done
} catch (error) {
// An error occurred
}
If not, chain your operations together by calling
then
on the promise returned bytraverse
:
let promise = Promise.resolve();
for (let i = 0; i < tableSize; ++i) {
promise = promise.then(() => traverse(i, obj));
}
promise
.then(() => {
// Done
})
.catch(error => {
// An error occurred
};
Updating `tra
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53972491%2fhow-to-execute-clipboard-copy-window-opening-event-handler-and-setinterval-in%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The only asynchronous thing I see in your code is traverse
's completion. So simply define traverse
to return a promise. Given the code in traverse
, this is probably easiest if you do it explicitly:
const traverse = (i, inObj) => {
return new Promise((resolve, reject) => { // <===========================
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
resolve(); // <===========================
}, 1000);
// *** Probably want to do a timeout here in case the window never loads
} else{
console.log('Failure!');
reject(); // <===========================
}
});
};
Then:
If you can use
async
syntax, write your loop usingawait
on the promise returned bytraverse
. Example:
// In an `async` function
try {
for (let i = 0; i < tableSize; ++i) {
await traverse(i, obj);
}
// Done
} catch (error) {
// An error occurred
}
If not, chain your operations together by calling
then
on the promise returned bytraverse
:
let promise = Promise.resolve();
for (let i = 0; i < tableSize; ++i) {
promise = promise.then(() => traverse(i, obj));
}
promise
.then(() => {
// Done
})
.catch(error => {
// An error occurred
};
Updating `tra
add a comment |
The only asynchronous thing I see in your code is traverse
's completion. So simply define traverse
to return a promise. Given the code in traverse
, this is probably easiest if you do it explicitly:
const traverse = (i, inObj) => {
return new Promise((resolve, reject) => { // <===========================
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
resolve(); // <===========================
}, 1000);
// *** Probably want to do a timeout here in case the window never loads
} else{
console.log('Failure!');
reject(); // <===========================
}
});
};
Then:
If you can use
async
syntax, write your loop usingawait
on the promise returned bytraverse
. Example:
// In an `async` function
try {
for (let i = 0; i < tableSize; ++i) {
await traverse(i, obj);
}
// Done
} catch (error) {
// An error occurred
}
If not, chain your operations together by calling
then
on the promise returned bytraverse
:
let promise = Promise.resolve();
for (let i = 0; i < tableSize; ++i) {
promise = promise.then(() => traverse(i, obj));
}
promise
.then(() => {
// Done
})
.catch(error => {
// An error occurred
};
Updating `tra
add a comment |
The only asynchronous thing I see in your code is traverse
's completion. So simply define traverse
to return a promise. Given the code in traverse
, this is probably easiest if you do it explicitly:
const traverse = (i, inObj) => {
return new Promise((resolve, reject) => { // <===========================
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
resolve(); // <===========================
}, 1000);
// *** Probably want to do a timeout here in case the window never loads
} else{
console.log('Failure!');
reject(); // <===========================
}
});
};
Then:
If you can use
async
syntax, write your loop usingawait
on the promise returned bytraverse
. Example:
// In an `async` function
try {
for (let i = 0; i < tableSize; ++i) {
await traverse(i, obj);
}
// Done
} catch (error) {
// An error occurred
}
If not, chain your operations together by calling
then
on the promise returned bytraverse
:
let promise = Promise.resolve();
for (let i = 0; i < tableSize; ++i) {
promise = promise.then(() => traverse(i, obj));
}
promise
.then(() => {
// Done
})
.catch(error => {
// An error occurred
};
Updating `tra
The only asynchronous thing I see in your code is traverse
's completion. So simply define traverse
to return a promise. Given the code in traverse
, this is probably easiest if you do it explicitly:
const traverse = (i, inObj) => {
return new Promise((resolve, reject) => { // <===========================
const number = document.getElementById('nid').rows[i].getElementsByTagName('td')[1].innerText;
const status = document.getElementById('nid').rows[i].getElementsByTagName('td')[4].innerText;
const file = `Item: ${name}`;
if(inObj[number] == "undefined" || inObj[poName] != status){
inObj[number] = status;
copyToClipboard(file);
let url = 'mysite.com/myroute';
let a = window.open(url);
a.focus();
let timer = setInterval(() => {
a.document.getElementsByClassName('anotherid')[1].click();
const i = a.document.getElementById('myframe');
i.contentWindow.focus();
i.contentWindow.print();
a.close();
clearInterval(timer);
console.log('Success!');
resolve(); // <===========================
}, 1000);
// *** Probably want to do a timeout here in case the window never loads
} else{
console.log('Failure!');
reject(); // <===========================
}
});
};
Then:
If you can use
async
syntax, write your loop usingawait
on the promise returned bytraverse
. Example:
// In an `async` function
try {
for (let i = 0; i < tableSize; ++i) {
await traverse(i, obj);
}
// Done
} catch (error) {
// An error occurred
}
If not, chain your operations together by calling
then
on the promise returned bytraverse
:
let promise = Promise.resolve();
for (let i = 0; i < tableSize; ++i) {
promise = promise.then(() => traverse(i, obj));
}
promise
.then(() => {
// Done
})
.catch(error => {
// An error occurred
};
Updating `tra
edited Dec 29 '18 at 19:18
answered Dec 29 '18 at 19:13
T.J. CrowderT.J. Crowder
682k12112091306
682k12112091306
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53972491%2fhow-to-execute-clipboard-copy-window-opening-event-handler-and-setinterval-in%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
Wrap the async operations in Promises and chain them or use async/await with them.
– Jared Smith
Dec 29 '18 at 18:58
Everything in your question except
setInterval()
is synchronous because JavaScript runs synchronously. The callback fromsetInterval()
will also run synchronously. It's just the timing function of the timer that will run asynchronously.– Scott Marcus
Dec 29 '18 at 18:59
Where's your loop?
– T.J. Crowder
Dec 29 '18 at 19:08
Thanks everyone for the replies! I have added my loop and a revision.
– God Complex
Dec 29 '18 at 19:13