Using app.ask more than once function - node.js

Within my function I would like to use app.ask('blah blah blah'); more than once. However when testing it, only the first app.ask() is spoken for which I expected it to also speak out the 2nd response too.
The function looks something like this:
for(var i = 0; i < array.length; i++) {
if (array == ##) {
app.ask(response 1)
} else {
app.ask(response 2)
}
}

That is correct - you can only use app.ask() once since that will send the response to the user. Once you send the response to the user, you must wait for the user to reply before you can send something else.
You would need to build your response in the loop and then send this to the user. Something like this
var response = '';
for(var i = 0; i < array.length; i++) {
if (array == ##) {
response += ' Message 1.';
} else {
response += ' Message 2.';
}
}
app.ask( response );

Related

getFileAsync causing Excel to crash

I'm building an office-js add-in for Excel. I need to upload the current workbook to a back end server. I've implemented an example from the Micrsoft Documentation, which seems to work fine the first time I call it, but on subsequent calls, it causes Excel to crash. I'm using Excel 365 version 1812 (build 11126.20132)
Here is the link to the example in the MS docs:
https://learn.microsoft.com/en-us/javascript/api/office/office.document
There are many examples on this page, to find the one I'm working from search for "The following example gets the document in Office Open XML" I've included the example below for ease of reference.
The code just get's the current file and dumps the characters to the console's log. It works fine the first but crashes Excel the second time--after it has shown the length of FileContent.
export function getDocumentAsCompressed() {
Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 /*64 KB*/ },
function (result) {
if (result.status == "succeeded") {
// If the getFileAsync call succeeded, then
// result.value will return a valid File Object.
var myFile = result.value;
var sliceCount = myFile.sliceCount;
var slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
console.log("File size:" + myFile.size + " #Slices: " + sliceCount);
// Get the file slices.
getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
}else {
console.log("Error:", result.error.message);
}
});
}
function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
file.getSliceAsync(nextSlice, function (sliceResult) {
if (sliceResult.status == "succeeded") {
if (!gotAllSlices) { // Failed to get all slices, no need to continue.
return;
}
// Got one slice, store it in a temporary array.
// (Or you can do something else, such as
// send it to a third-party server.)
// console.log("file part",sliceResult.value.data)
docdataSlices[sliceResult.value.index] = sliceResult.value.data;
if (++slicesReceived == sliceCount) {
// All slices have been received.
file.closeAsync();
onGotAllSlices(docdataSlices);
}
else {
getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
}
}
else {
gotAllSlices = false;
file.closeAsync();
console.log("getSliceAsync Error:", sliceResult.error.message);
}
});
}
function onGotAllSlices(docdataSlices) {
var docdata = [];
for (var i = 0; i < docdataSlices.length; i++) {
docdata = docdata.concat(docdataSlices[i]);
}
var fileContent = new String();
for (var j = 0; j < docdata.length; j++) {
fileContent += String.fromCharCode(docdata[j]);
}
console.log("fileContent.length",fileContent.length)
// Now all the file content is stored in 'fileContent' variable,
// you can do something with it, such as print, fax...
}
Here is the result
File size:21489 #Slices: 1
fileContent.length 21489
Original example from Microsoft documentation (https://learn.microsoft.com/en-us/javascript/api/office/office.document)
// The following example gets the document in Office Open XML ("compressed") format in 65536 bytes (64 KB) slices.
// Note: The implementation of app.showNotification in this example is from the Visual Studio template for Office Add-ins.
function getDocumentAsCompressed() {
Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 /*64 KB*/ },
function (result) {
if (result.status == "succeeded") {
// If the getFileAsync call succeeded, then
// result.value will return a valid File Object.
var myFile = result.value;
var sliceCount = myFile.sliceCount;
var slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
app.showNotification("File size:" + myFile.size + " #Slices: " + sliceCount);
// Get the file slices.
getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
}
else {
app.showNotification("Error:", result.error.message);
}
});
}
function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
file.getSliceAsync(nextSlice, function (sliceResult) {
if (sliceResult.status == "succeeded") {
if (!gotAllSlices) { // Failed to get all slices, no need to continue.
return;
}
// Got one slice, store it in a temporary array.
// (Or you can do something else, such as
// send it to a third-party server.)
docdataSlices[sliceResult.value.index] = sliceResult.value.data;
if (++slicesReceived == sliceCount) {
// All slices have been received.
file.closeAsync();
onGotAllSlices(docdataSlices);
}
else {
getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
}
}
else {
gotAllSlices = false;
file.closeAsync();
app.showNotification("getSliceAsync Error:", sliceResult.error.message);
}
});
}
function onGotAllSlices(docdataSlices) {
var docdata = [];
for (var i = 0; i < docdataSlices.length; i++) {
docdata = docdata.concat(docdataSlices[i]);
}
var fileContent = new String();
for (var j = 0; j < docdata.length; j++) {
fileContent += String.fromCharCode(docdata[j]);
}
// Now all the file content is stored in 'fileContent' variable,
// you can do something with it, such as print, fax...
}
// The following example gets the document in PDF format.
Office.context.document.getFileAsync(Office.FileType.Pdf,
function(result) {
if (result.status == "succeeded") {
var myFile = result.value;
var sliceCount = myFile.sliceCount;
app.showNotification("File size:" + myFile.size + " #Slices: " + sliceCount);
// Now, you can call getSliceAsync to download the files,
// as described in the previous code segment (compressed format).
myFile.closeAsync();
}
else {
app.showNotification("Error:", result.error.message);
}
}
);
Since you're using Excel, have you tried the CreateWorkbork API? Might be a good workaround if the Document API has a bug, like Xuanzhou indicated earlier.
Here's a CreateDocument snippet that you can load into Script Lab. It shows how to create a Workbook copy based on an existing file.
Hope all that is helpful.
We already have a fix for it now. But the fix still need some time to go to production. Please try it several days later and let me know if the issue still exists. Thanks.

NodeJS - Throw inside nested loop in Sails.js

I'm new in NodeJS and Sails.js. I get stuck when run API script like here :
try{
for(let i = 0 ; i < 10 ; i++ ) {
for(let j = 0; j < 10; j++) {
await doSomething(); // asume the API using async
throw 'a';
}
}
} catch (e) {
return e;
}
When I run the first time the script it's ok (running well), but when I run the second time, it is stuck (nothing return). When I check the console, no error appears.
It will work again if I restart the API.
What happens to my script ? can anyone explain? Why it just run 1 time (return a) but cannot started again when i call again the API without restart it first
you should throw Error not a string, so your could should look like this
throw new Error('a')
also the script won't continue after first loop cause you are throwing.
I hope its not stuck. It will return the string 'a'. You can check that by adding console.log
try {
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
throw 'a';
}
}
} catch (e) {
console.log('Error: ', e);
return e;
}
This will print Error: a all the time and return 'a'
Note: As mentioned you should throw new Error instead of string 'a'.
If you want to break the loop on condition. Just set i = 11; j = 11;

Custom module data returning successfully but not displaying

I have a custom module in file help.js, the function name there is getfriends(req,res,next,user). The user is whose friends I want to get.
for (var i = 0; i < users.length; i++) {
for (var j = 0; j < docs.length; j++) {
if (docs[j].user1 == users[i].username) {
if (docs[j].user1 != req.body.user) {
friends.push(users[i]);
}
} else if (docs[j].user2 == users[i].username) {
if (docs[j].user2 != req.body.user) {
friends.push(users[i]);
}
}
}
if (i == users.length-1) {
console.log("friends",friends); //it displays my desired result and so I think the return is successfull
return(friends);
}
}
Now where I receive the data, I do this and data is not being displayed.
console.log(Help.getfriends(req,res,next,req.session.user));
I have tried doing :-
somevar = Help.getfriends(req,res,next,req.session.user);
console.log(somevar);
The module is being called, it is displaying perfect result. Please guide me how to get the data properly from the custom module.
Also, above I have done,
var Help = require('./help');
Your function is asynchronous.
When you console.log(...) <== there is no result yet.
So i'ts expected that you console.log undefined.
More info about nodejs asyncronous nature.

Send thousand dns request and save to csv - performance

I have problem with sending big amount of domains to check if they exist. I'm using node native dns and check in MX records.
I have array of 60k domains I send this to function that checking duplicated value and return unique domains, then I loop for each value and send to function: that verify domain if is valid, send dns request, check what MX received and return correct value, then I save it to csv file. Unfortunately it's saving to file only 1,2 to 1,5k domains not more. I don't received any error just stop saving. Maybe someone know what I doing wrong.
ev1.checkdomains(csvdomains, MXtocheck, function(uniquedata) {
var wstream = fs.createWriteStream(path);
for(i = 0; i < uniquedata.length; i++){
var tmpdomian = uniquedata[i].toString();
ev.searchMX(tmpdomian, arrMX, function(valid, domain, comment){
if(valid){
wstream.write(domain + ',' + comment + '\n');
}
});
}
also I think is important to noted that insite searchMX function I checking returned MX if maching array with MX servers that I don't want to have - that is not efficient because I'm using double loop, meaby this is the reason, but I don't know how to make this better.
dns.resolve(domain, 'MX', function(err, addresses) {
valid = false;
if (err) {
valid = false;
comment = 'MX record not exist';
}
else if (addresses && addresses.length > 0) {
var tmp_comment = '';
for(var i = 0; i < addresses.length; i++){
for(var j = 0; j < arrMX.length; j++){
if(addresses[i].exchange == arrMX[j]){
valid = false;
comment = 'is in wrong MX records ' + addresses[i].exchange;
cb(valid, email, comment);
return;
}
}
tmp_comment += ' ' + addresses[i].exchange;
}
if(!valid){
valid = true;
comment = tmp_comment;
}
}
else {
valid = false;
comment = 'error not specify'
}
cb(valid, email, comment);
});
Thanks a million for any help to improve this code, or figure out what is wrong.

Siebel eScript varargs function always throws an exception

according to Siebel documentation, eScript supports varargs.
The following sample is taken from the Siebel documentation:
function SumAll()
{
var total = 0;
for (var ssk = 0; ssk < SumAll.arguments.length; ssk++)
{
total += SumAll.arguments[ssk];
}
return total;
}
However, if I call this method like SumAll(1,2,3) I get the following exception:
TypeError: Can't convert 'Undefined' to Object. Service.SumAll line xxx
where xxx is the line number of the for statement.
Any idea, why?
Thanks!
Instead of typing "SumAll.arguments", try using just "arguments" like this:
function SumAll()
{
var total = 0;
for (var ssk = 0; ssk < arguments.length; ssk++)
{
total += arguments[ssk];
}
return total;
}

Resources