Trying to get if statement to determine 'context' of addon app - javascript

I'm working this Google Workspace Add-on app, I'm trying to get a function that sets the appropriate function for calling the document id depending on if it's called in the context of drive, docs, sheets, etc.
function checkContext(event){
var itemId;
Logger.log(event)
if (DocumentApp.getActiveDocument().getId() != null && DocumentApp.getActiveDocument().getId() != undefined)
{
itemId = DocumentApp.getActiveDocument().getId();
Logger.log(itemId);
}
else if (e.drive.selectedItems[0].id != null && e.drive.selectedItems[0].id != undefined){
var itemId = e.drive.selectedItems[0].id;
Logger.log(itemId);
}
else if (SpreadsheetApp.getActive().getId() != null && SpreadsheetApp.getActive().getId() != undefined){
var itemId = SpreadsheetApp.getActive().getId();
Logger.log(itemId);
}
else {
var itemId = SlidesApp.getActivePresentation().getId();
Logger.log(itemId);
}
As you can see, I've attempted to achieve this with a nested if statement, where the itemId variable is set to the appropriate context depending on which getId() does NOT fail. Despite my best efforts, I always get the
TypeError: Cannot read property 'getId' of null
error every time the my function is triggered.

This is the solution I ended up with, using Cooper's insight about commonEventObjects. This function returns the a string for getting a document ID in the appropriate context. The returned string can then be run with eval()to return a doc id in function with the same event.
function serveDocCall(event){
var context = event.commonEventObject.hostApp
var docCall;
if (context == "DOCS")
{docCall = 'DocumentApp.getActiveDocument().getId()';
Logger.log(docCall);}
else if (context == "DRIVE"){
var docCall = 'event.drive.selectedItems[0].id';
Logger.log(docCall);}
else if (context == "SHEETS"){
var docCall = 'SpreadsheetApp.getActive().getId()';
Logger.log(docCall);}
else {
var docCall = 'SlidesApp.getActivePresentation().getId()';
Logger.log(docCall);}
return docCall;
}

Related

Chrome Debugger can't access variable of static callback

I have a static class with only static method written in javascript. The pourpose of the calss and the method is to be a callback container for a certain kind of ajax call.
From the HTML page, sometimes an ajax call is raised and the static method of static class described above, is passed as callback argument.
All work just fine, i also remeber to have debugged the callback previously, but after the last chrome update, even if i can debug the callback, i can't see variable value.
I can't access variable value (when a breackpoint in the static callback is hit, so in the same scope of breakpoint) with the console nor with the watch.
This is the callback class with static method (it's a bit triky, but i prefer not simplify it because maybe the problem reside in the callback code)
/**
* List of defaults callback
* */
class CallbackDefaults {
/**
* Callback used to update price of priced articles
* #param {object} data Page of ArticleDto with actual prices
*/
static priceUpdateCallback = function (data) {
var callbackSource = "getPricesAndStock_callback";
try {
if (!data || data.Success == false || !data.ReturnData || !data.ReturnData.PageContent && data.ReturnData.PageContent.length > 0)
return;
for (var index = 0; index < data.ReturnData.PageContent.length; index++) {
var currentArticle = data.ReturnData.PageContent[index];
var item = document.querySelector(".cgi-priced[ref-code='" + currentArticle.Code + "']");
if (item && currentArticle && currentArticle.Attributes && currentArticle.Attributes.PriceData && currentArticle.Attributes.PriceData.TaxedPrice) {
var priceData = currentArticle.Attributes.PriceData;
var finalPrice = globals.isVatIncluded ? priceData.TaxedPrice : priceData.CalculatedPrice;
let precetageBadge = item.querySelector(".discount-percentage") || { textContent: "" };
let originalPrice = item.querySelector(".original-price") || { textContent: "" };
let discountedPrice = item.querySelector(".discounted-price") || { textContent: "" };
let buyButton = item.querySelector(".buy") || { disabled: false };
var percentage = globals.trustAS400Perc ?
finalPrice.DiscountPercentage :
finalPrice.CalculatedDiscountPercentage;
var percentageString = globals.trustAS400Perc ?
finalPrice.DiscountPercAsString :
finalPrice.CalculatedDiscountPercAsString;
if (!percentage || percentage <= 0)
precetageBadge?.classList?.add("d-none");
else
{
if (precetageBadge?.classList?.contains("d-none"))
precetageBadge?.classList?.remove('d-none');
precetageBadge.textContent = percentageString || "";
}
if (finalPrice.NetPriceAsStringWithCurrency == finalPrice.GrossPriceAsStringWithCurrency)
originalPrice?.classList?.add("d-none");
else
{
originalPrice.textContent = finalPrice.GrossPriceAsStringWithCurrency || "";
}
if (finalPrice.NetPriceAsStringWithCurrency)
discountedPrice.textContent = finalPrice.NetPriceAsStringWithCurrency || "";
else
buyButton.disabled = true;
//update quantity limit
var inSpinner = $(item).find("input[meta=original]");
if (inSpinner && inSpinner.length == 1) {
var updatedQuantity = currentArticle?.Attributes?.StockInformation?.AvailableQuantityFromCgi;
if (updatedQuantity && updatedQuantity > 0) {
inSpinner.inputSpinner("destroy");
inSpinner[0].max = updatedQuantity;
inSpinner.inputSpinner(globals.inputSpinnerConf);
}
}
}
}
}
catch (callbackErr) {
ClientLogManager.logError(callbackSource, callbackErr);
Toaster.getToast("tstTemplatePriceError");
}
};
}
In JQuery ajax success function i call the callback in the following way :
success: function (data) {
try
{
CallbackDefaults.priceUpdateCallback(data);
}
catch (callErr) {
ClientLogManager.logError(source, callErr)
}
}
When i place a breack point into priceUpdateCallback, for example on the following line :
var callbackSource = "getPricesAndStock_callback";
And the run code, the breakpoint will be hit, but i can't see the actual value of 'callbackSource' variable.
I can't get the value hovering, placing the variable in the watch or writing it into the console.
If i try to access the variable through console i get this error :
VM255:1 Uncaught ReferenceError: callbackSource is not defined
at eval (eval at priceUpdateCallback (CallbackDefaults.js:1:1), <anonymous>:1:1)
at priceUpdateCallback (CallbackDefaults.js:13:30)
at Object.success (ConnectionManager.js:169:25)
at c (jquery-3.6.0.min.js:2:28327)
at Object.fireWith [as resolveWith] (jquery-3.6.0.min.js:2:29072)
at l (jquery-3.6.0.min.js:2:79901)
at XMLHttpRequest.<anonymous> (jquery-3.6.0.min.js:2:82355)
I can't understand why, because i remember to have debugged that function before, and seems strange that the new chrome version just introduce a so blatant bug.
--Edit :
i am using Chrome 98.0.4758.102 (Official Build) (64-bit)

Google App Script - Function Returning Undefined

I'm trying to call a function that gets a channel ID when given a Slack Workspace and channel name. I can get the correct result within the function, but when I try to call the function elsewhere, it is returning undefined.
Function to get the channel ID `
//GET CHANNEL ID FROM LIST OF ALL CHANNELS IN WORKSPACE
function getChannelID(workspaceName, pageLimit, channelName, nextCursor){
var channelListResponseURL = 'https://slack.com/api/conversations.list';
var payload = {
'limit': pageLimit,
'types': 'public_channel, private_channel',
'cursor' : nextCursor
};
var options = createURLargs(workspaceName, payload);
var channelListResponse = UrlFetchApp.fetch(channelListResponseURL, options);
var channelListJson = channelListResponse.getContentText();
var channelListData = JSON.parse(channelListJson);
//iterate through each channel in the returned JSON object and sets the channel ID for the one matching the channelName
for (var i in channelListData.channels){
if(channelListData.channels[i].name == channelName){
var channelID = channelListData.channels[i].id;
Logger.log('FOUND CHANNEL ID: '+ channelID);
return channelID;// IF CHANNEL ID FOUND, THEN EXIT getChannelID FUNCTION AND RETURN CHANNEL ID
}
}
// IF NO CHANNEL ID IS FOUND, THEN CHECK TO SEE IF PAGINATION IS IN EFFECT, UPDATE CURSOR, AND RERUN getChannelID FUNCTION
if (channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != ""){
nextCursor = channelListData.response_metadata.next_cursor;
getChannelID(workspaceName, pageLimit, channelName, nextCursor);
} else {
// IF CHANNEL PAGINATION IS NOT IN EFFECT, OR REACHED LAST PAGE AND NO RESULT IS FOUND
return 'No Channel Found in Workspace';
}
}
`
I can clearly see the 'FOUND CHANNEL ID: CXXXXXX' string in the logger, so I'm sure it finds it properly.
But when I call this getChannelID from the main function, it is returning undefined.
var channelID = getChannelID(workspaceName, pagLimit, channelName, nextCursor);
Logger.log(channelID);
The weird thing is this seems to work when the JSON object from Slack isn't paginated, but when the results are returned paginated, I just seem to get undefined.
Any ideas why the result it's returning is undefined, even though it works in the function?
I think that in your recursive function, the value is not returned. So how about this modification?
From :
if (channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != ""){
nextCursor = channelListData.response_metadata.next_cursor;
getChannelID(workspaceName, pageLimit, channelName, nextCursor);
} else {
// IF CHANNEL PAGINATION IS NOT IN EFFECT, OR REACHED LAST PAGE AND NO RESULT IS FOUND
return 'No Channel Found in Workspace';
}
To :
if (channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != ""){
nextCursor = channelListData.response_metadata.next_cursor;
return getChannelID(workspaceName, pageLimit, channelName, nextCursor); // Modified
} else {
// IF CHANNEL PAGINATION IS NOT IN EFFECT, OR REACHED LAST PAGE AND NO RESULT IS FOUND
return 'No Channel Found in Workspace';
}
Note :
When channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != "" is true, no value is returned. So I added return.
If this didn't work yet, please tell me. I would like to modify it.
Added :
In my understanding, when the recursive function is run, the process returns to the line which was run. In order to confirm this, I prepared 3 sample functions.
Function 1
function foo1(value) {
if (value == "") {
foo1("bar");
} else {
return "ok";
}
}
Function 2
function foo2(value) {
if (value == "") {
return foo2("bar");
} else {
return "ok";
}
}
Function 3
function foo3(value) {
if (value == "") {
foo3("bar");
}
return "ok";
}
When these functions is run by as follows,
var res1 = foo1("");
var res2 = foo2("");
var res3 = foo3("");
res1, res2 and res3 are undefined, ok and ok, respectively.

Checking for null in Javascript but still receiving TypeError

When I run this code, I receive this error:
TypeError: Cannot read property 'outerHTML' of null
Here is my code:
let image = document.querySelector('.gallery__large-image-link');
if (image !== null || image !== '' || typeof(image) !== 'undefined') {
var html = image.outerHTML;
//do stuff
}
Since you're using ||, if any of the conditions are true, the block executes - and given the !== tests, the block will always execute. Use && instead. Also, correct your typeof syntax:
const image = document.querySelector('.gallery__large-image-link');
if (image !== null && image !== '' && typeof image !== 'undefined') {
const html = image.outerHTML;
//do stuff
}
Or simply check to see if image is truthy:
const image = document.querySelector('.gallery__large-image-link');
if (image) {
const html = image.outerHTML;
//do stuff
}
You can just use this code
let image = document.querySelector('.gallery__large-image-link');
if (image) { // this will check for undefined and null
var html = image.outerHTML;
//do stuff
}

Why am i getting 'Unable to get property 'pAmt' of undefined or null reference'

My Jquery Datatables is populated without problems,i am using:-
Datatables version 1.10.12 and
Jquery version 1.11.1
List item
But after editing and saving ,i am getting "Unable to get property 'pAmt' of undefined or null reference".Below is the function which is called after clicking save button
function onDealPaymentChange(dealPmtId) {
var theForm = document.getElementById("updateDealPmtForm" + dealPmtId);
var amount = trim(theForm.pAmt.value, "both");
var invDate = theForm.pInvDate.value;
var recvDate = theForm.pRecDate.value;
if (isNaN(amount) || amount == "") {
alert("Invalid payment amount.")
} else if (!isDate(invDate, "Invoice")) {
//alert("Invalid invoice date");
} else if (recvDate != "" && !isDate(recvDate, "Received")) {
//alert("Invalid Received Date");
} else {
theForm.submit();
}
}
The culprit would be this line:
var amount = trim(theForm.pAmt.value, "both");
At the time where this function is executed, theForm is either null or undefined. If you were to comment out the line mentioned, I would expect that the next error to occur would mention something about Unable to get property 'pInvDate' of undefined or null reference.
Throw a console.log(theForm); statement just above the var amount = ...; line, it should show you that theForm is undefined or null at the browser console.

Checking for undefined causes undefined error

Trying to check if some variables contain things, because they throw errors and break the ajax function when they don't. Problem is that just checking if data[2][0] contains something causes the following error:
Uncaught TypeError: Cannot read property '0' of undefined
I'd very much prefer not to check this in a previous stage. How do I check if data[2][0] is defined, without causing the actual checking to break my js?
Code:
//ajax ^
success: function(data){
var xp = data[0][0]; //Contains a string
var yp = data[1][0]; //Contains a string
var zp = data[2][0]; //Is not set, fails here
if(xp === ''){ //Tried using null & undefined here aswell
//Do nothing
} else {
var one = data[0][0];
var oneH = data[0][1];
var oneS = data[0][2];
}
if(yp === ''){
//Do nothing
} else {
var two = data[1][0];
var twoH = data[1][1];
var twoS = data[1][2];
}
if(zp === ''){
//Do nothing
} else {
var three = data[2][0];
var threeH = data[2][1];
var threeS = data[2][2];
}
//ajax continues v
Any help will be much appreciated.
You should check if a variable is undefined using typeof, not with an equality check against '':
if (typeof myVar === 'undefined')
You can also check if a variable is an array using Array.isArray(myVar)
I would check to see if data[2] exists first, and then redefine zp if it does.
var zp = data[2];
if (zp) zp = zp[0];

Categories